Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/20: Рейтинг темы: голосов - 20, средняя оценка - 4.75
3 / 3 / 3
Регистрация: 26.09.2009
Сообщений: 77
1

Асинхронные операции на C#

30.08.2011, 18:32. Показов 3807. Ответов 9
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Реализую обмен данными с устройством по USB-каналу (bulk передача) с использованием функций WinUSB API.
Хочу реализовать асинхронное чтение (функция WinUsb_ReadPipe), по типу того как это стандартно делается на "C" с использованием структуры OVERLAPPED и функций WaitForMultipleObjects или WaitForSingleObject.

Подскажите, как это реализовать на C#.
Насколько я понимаю, необходимо подключить API-функции при помощи DllImport, но будет ли это работать? И ещё не ясно как объявить указатель на структуру OVERLAPPED. Если есть примеры, дайте, пожалуйста, ссылку.

Или может есть какой-нибудь другой способ организации асинхронной работы на C#.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
30.08.2011, 18:32
Ответы с готовыми решениями:

Асинхронные операции
Есть у меня источник с элементами (ObservableCollection), и специальные коллекции "отображения",...

Асинхронные операции
Console.WriteLine("Some code"); using (var fs = new System.IO.FileStream("File.txt",...

Синхронные/асинхронные операции
Подскажите примерный паттерн для приостановки скажем бесконечного цикла, который уже запущен каким...

Асинхронные операции
Всем привет, имею следующий вопрос. Допустим, есть форма или JFrame, на которой есть кнопка и...

9
мастер топоров
916 / 741 / 101
Регистрация: 16.08.2009
Сообщений: 1,476
30.08.2011, 19:41 2
в C# есть синхронные операции чтения потока: Stream.BeginRead
можно создать поток из файла, который на флешке и читать с него информацию асинхронно
0
3 / 3 / 3
Регистрация: 26.09.2009
Сообщений: 77
30.08.2011, 21:32  [ТС] 3
Я работаю не с флешкой и файлами, а с устройством, которое периодически выкидывает в канал данные, которые надо вычитывать. Удобно это сделать в потоке, который приостанавливается функцией WaitForSingleObject до прихода байта, что позволяет разгрузить программу.
Думаю, что должен быть альтернативный механизм в C#, подскажите как реализовать.
0
3 / 3 / 3
Регистрация: 26.09.2009
Сообщений: 77
01.09.2011, 09:47  [ТС] 4
Как организовать непосредственно асинхронное чтение я представляю - BeginInvoke и т.д., ВАЖНО реализовать работу именно с ПЕРЕКРЫВАЕМЫМИ операциями, чтобы усыплять поток на время чтения и не терять процессорное время.
0
45 / 44 / 7
Регистрация: 15.10.2008
Сообщений: 320
05.09.2011, 17:14 5
попробуй тут почитать Асинхронные операции и AsyncEnumerator.
0
3 / 3 / 3
Регистрация: 26.09.2009
Сообщений: 77
05.09.2011, 17:46  [ТС] 6
По-моему всё не то. Здесь нет усыпления (приостановки выполнения) потока при выполнении асинхронных операций, а значит поток продолжает периодически вызываться и жрет процессорное время.
0
Эксперт .NET
4432 / 2092 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
05.09.2011, 19:43 7
Сильно не вникал в вопрос, бегло глянул. Не это ли нужно?
AutoResetEvent
Или вообще посмотри какие есть классе в пространстве имён System.Threading
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
using System;
using System.Threading;
 
namespace ConsApp_ThreeThreads
{
    class Program
    {
        static void Main(string[] args)
        {
            Random rnd = new Random();
            long account = 0;
            AutoResetEvent accountChangedEv = new AutoResetEvent(false);
 
            var incThread = new Thread(new ThreadStart(() =>
            {
                while (!IsFinished(account))
                {
                    Interlocked.Add(ref account, rnd.Next(1, 100));
                    accountChangedEv.Set();
 
                    Thread.Sleep(rnd.Next(100, 3001));
                }
            }));
 
            var decThread = new Thread(new ThreadStart(() =>
            {
                while (!IsFinished(account))
                {
                    Interlocked.Add(ref account, -rnd.Next(1, 100));
                    accountChangedEv.Set();
 
                    Thread.Sleep(rnd.Next(100, 3001));
                }
            }));
 
            var printThread = new Thread(new ThreadStart(() =>
            {
                while (!IsFinished(account))
                {
                    accountChangedEv.WaitOne();
                    Console.WriteLine("Account changed to " + account);
                }
            }));
 
            printThread.Start();
            incThread.Start();
            decThread.Start();
 
            incThread.Join();
            decThread.Join();
            printThread.Join();
 
            Console.WriteLine("done!");
            Console.ReadKey();
        }
 
        static bool IsFinished(long account)
        {
            return account < -10000 || account > 10000;
        }
    }
}
0
3 / 3 / 3
Регистрация: 26.09.2009
Сообщений: 77
06.09.2011, 12:12  [ТС] 8
Спасибо, вроде похоже на то, что нужно. Осталось только разобраться как эти AutoResetEvent (ну или EventWaitHandle) правильно в OVERLAPPED запихнуть и в перекрываемую операцию передать.
0
1274 / 975 / 113
Регистрация: 12.01.2010
Сообщений: 1,971
06.09.2011, 15:57 9
Показал бы код на С лучше, судя по описанию этого WinUsb_ReadPipe никакие ресет евенты не помогут тут

Да и вообще в дотнете даже есть готовая реализация OVERLAPPED http://msdn.microsoft.com/en-u... apped.aspx

Добавлено через 21 минуту
А если немного погулить что-то в стиле "Winusb net wrapper" то можно даже найти готовые решения, например
http://www.asyncop.net/MTnPDir... +Component
0
3 / 3 / 3
Регистрация: 26.09.2009
Сообщений: 77
06.09.2011, 16:22  [ТС] 10
Вот код на C, который хочу втащить в .NET
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
extern "C" DWORD PASCAL EXPORT
ReadUSBPacket(LMUSB_HANDLE hUSB, unsigned char *pcBuffer, unsigned long ulSize,
              unsigned long *pulRead, unsigned long ulTimeoutmS, HANDLE hBreak)
{
    BOOL bResult;
    DWORD dwError;
    OVERLAPPED sOverlapped;
    HANDLE phSignals[2];
    tDeviceInfoWinUSB *psDevInfo = (tDeviceInfoWinUSB *)hUSB;
 
    //
    // Check for bad parameters.
    //
    if(!hUSB || !pcBuffer || !pulRead || !ulSize)
    {
        return(ERROR_INVALID_PARAMETER);
    }
 
    //
    // Tell WinUSB how to signal us when reads are completed (if blocking)
    //
    sOverlapped.hEvent = psDevInfo->hReadEvent;
    sOverlapped.Offset = 0;
    sOverlapped.OffsetHigh = 0;
 
    //
    // Perform the read.
    //
    bResult = WinUsb_ReadPipe(psDevInfo->winUSBHandle,
                              psDevInfo->bulkInPipe,
                              pcBuffer,
                              ulSize,
                              pulRead,
                              &sOverlapped);
 
    //
    // A good return code indicates success regardless of whether we performed
    // a blocking or non-blocking read.
    //
    if(bResult)
    {
        dwError =  ERROR_SUCCESS;
    }
    else
    {
        //
        // An error occurred or the read will complete asynchronously.
        // Which is it?
        //
        dwError = GetLastError();
 
        //
        // Check for error cases other than the one we expect.
        //
        if(dwError == ERROR_IO_PENDING)
        {
            //
            // The IO is pending so wait for it to complete or for a
            // timeout to occur.
            //
            phSignals[0] = psDevInfo->hReadEvent;
            phSignals[1] = hBreak;
            dwError = WaitForMultipleObjects(hBreak ? 2 : 1, phSignals, FALSE,
                                             ulTimeoutmS);
 
            //
            // At this stage, one of three things could have occurred.
            // Either we read a packet or we timed out or the break
            // signal was detected.  Which was it?
            //
            if(dwError == WAIT_OBJECT_0)
            {
                //
                // The overlapped IO request completed so check to see how
                // many bytes we got.
                //
                bResult = GetOverlappedResult(psDevInfo->deviceHandle,
                                              &sOverlapped,
                                              pulRead, FALSE);
                if(bResult)
                {
                    dwError = ERROR_SUCCESS;
                }
                else
                {
                    //
                    // Something went wrong.  Return the Windows error code.
                    //
                    dwError = GetLastError();
                }
            }
            else
            {
                //
                // Something went wrong - abort the transfer
                //
                WinUsb_AbortPipe(psDevInfo->winUSBHandle,
                                 psDevInfo->bulkInPipe);
 
                //
                // Was the break event signalled?
                //
                if(dwError  == (WAIT_OBJECT_0 + 1))
                {
                    //
                    // The break event was signalled - abort the read and return.
                    //
                    dwError = WAIT_OBJECT_0;
                }
            }
        }
    }
 
    //
    // Pass the result back to the caller.
    //
    return(dwError);
}
А Overlapped Class - это я так понял .NET Framework 4, а он у всех пользователей установлен.
0
06.09.2011, 16:22
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
06.09.2011, 16:22
Помогаю со студенческими работами здесь

Как работают асинхронные операции в Qt
Хочу понять механику. Вот я вызываю QTcpSocket::connectToHost(...). Вызов неблокирующий. Через...

Как отменить все асинхронные операции отдельного потока сервера ?
Добрый день, я хотел бы реализовать принцип работы на своём сервере(Boost asio) когда потоки и...

Асинхронные делегаты
Здравствуйте ! Подскажите пожалуйста, (программа рабочая ) для чего в методе public bool...

Асинхронные процессы
В гугле не смог найти никакой пример, изложена только теория, из которой ничего не понял. На форме...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru