Bla*_*Box 8 c# multithreading asynchronous async-await .net-4.5
当需要在整个应用程序生命周期中运行I/O侦听器时,在4.5框架上运行C#5.0时,首选哪种并发模型?
我已经确定了生产者 - 消费者模式最适合处理我收到的东西,但基础设施应该支持它的想法?
请问一个简单的Thread thread = new Thread(ThreadStart(method))建议吗?或者可能是首选Task或Async/Await型号?
这是一个快速的问题,但由于我在设计初期,我宁愿确保基础强大.我对其他语言的直觉反应是,在后台运行一个简单的线程是最好的,但是C#中过多的并行框架让我偏离了正轨.
如果有任何相关性,我的应用程序中的轮询时间将由I/O读取超时处理.
I/OI指的是FTDI设备,其中字节可以随时由设备推送到PC,具体取决于板载控制器的状态.因此,我总是需要准备好拾取数据并进行处理.我正在使用的API基于FTDI供应商提供的D2XX DLL.
I/OI 指的是 FTDI 设备,该设备可以随时将字节推送到 PC,具体取决于板载控制器的状态。因此,我总是需要准备好获取数据并进行处理。我使用的 API 基于 FTDI 供应商提供的 D2XX DLL。
快速搜索就会发现这个文档。简单地看一下它表明您需要打开设备设备以进行重叠 I/O,以实现高效的侦听器。以下是文档中的相关示例代码(C++):
FT_HANDLE ftHandle; // setup by FT_W32_CreateFile for overlapped i/o
char Buf[256];
DWORD dwToRead = 256;
DWORD dwRead;
OVERLAPPED osRead = { 0 };
osRead.hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
if (!FT_W32_ReadFile(ftHandle, Buf, dwToRead, &dwRead, &osRead))
{
if (FT_W32_GetLastError(ftHandle) == ERROR_IO_PENDING)
{
// write is delayed so do some other stuff until ...
if (!FT_W32_GetOverlappedResult(ftHandle, &osRead, &dwRead, FALSE))
{
// error
}
else
{
if (dwToRead == dwRead)
{
// FT_W32_ReadFile OK
}
else
{
// FT_W32_ReadFile timeout
}
}
}
}
else
{
// FT_W32_ReadFile OK
}
Run Code Online (Sandbox Code Playgroud)
这里的关键点是这个评论:“ //写入被延迟,所以做一些其他的事情直到...... ”[顺便说一句,我相信这是一个错字,应该在那里读取而不是写入]。
如何处理这种延迟?要使您的侦听器异步,您必须异步等待内核事件对象。我刚刚回答了一个有关如何有效地做到这一点的相关问题。在您的情况下,它可能看起来像这样(C# 中的草图):
async Task<Data> ReadFtdiAsync()
{
// ...
var completedMre = new ManualResetEvent(false);
osRead.hEvent = completedMre.SafeWaitHandle.DangerousGetHandle();
if (!FT_W32_ReadFile(ftHandle, Buf, dwToRead, ref dwRead, ref osRead))
{
if (FT_W32_GetLastError(ftHandle) == ERROR_IO_PENDING)
{
// asynchronous completion
// read is delayed, so await
var tcs = new TaskCompletionSource<bool>();
ThreadPool.RegisterWaitForSingleObject(
completedMre,
(s, t) => tcs.SetResult(true),
null, Timeout.Infinite, true)
// resume asynchronously when the event is signalled
await tcs.Task;
if (!FT_W32_GetOverlappedResult(ftHandle, ref osRead, ref dwRead, FALSE))
{
// error
throw new InvalidOperationException("I/O error");
}
else
{
if (dwToRead == dwRead)
{
// FT_W32_ReadFile OK
// retrieve and return the data
return data;
}
else
{
// FT_W32_ReadFile timeout
throw new TimeoutException();
}
}
}
}
else
{
// synchronous completion
// retrieve and return the data
// or handle an error
return data;
}
}
Run Code Online (Sandbox Code Playgroud)
该代码可以并且应该通过适当的超时和取消逻辑来改进。然后你可以简单地ReadFtdiAsync循环调用:
while (true)
{
cancellationToken.ThrowIfCancellationRequested();
var data = await ReadFtdiAsync(cancellationToken);
// the execution will resume here likely on a different thread
ProcessData(data);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
798 次 |
| 最近记录: |