使用任务进行连续轮询 [英] Continuous polling using Tasks

查看:88
本文介绍了使用任务进行连续轮询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我一直使用Threads/BackgroundWorker的东西,但是我试图将其迁移到Task的处事方式.

This is something I've always used Threads / BackgroundWorker for, but am trying to migrate over to Task way of doing things.

假设我有一个第三方SDK,可用来从USB端口读取字节.该读取调用处于阻塞状态,如果未读取任何字节,则在100 ms后超时,并返回null.如果读取了字节,它将立即返回,并返回读取字节的byte []数组.

Let's say I have a 3rd party SDK I use to read bytes from a USB port. That read call is blocking and times out after 100 ms if no bytes are read, returning null. It returns immediately if bytes are read, returning byte[] array of read bytes.

因此,我基本上需要不断地进行轮询,并通过调用解析函数对接收到的字节采取措施.这是WPF应用程序,因此返回的字节应该能够传递到UI线程函数.

So I basically need to keep polling over and over, and take action on received bytes, by calling Parsing function. It's a WPF application, so the returned bytes should be able to be passed to a UI thread function.

执行此操作的正确方法是什么?到目前为止,这是我所拥有的,并且似乎可以正常工作,但是我想确保这是使用TPL进行操作的正确方法:

What's the right approach to doing this? This is what I have so far, and it seems to work, but I want to make sure it's the right way of doing things using TPL:

private void _connectUsbButton_Click(object sender, RoutedEventArgs e)
{
   ListenForUsbMessagesAsync();
}

private async void ListenForUsbMessagesAsync()
{
    while (true)
    {
        byte[] readBytes = await ReadBytesAsync();
        Parse(readBytes);
    }
}

private Task<byte[]> ReadBytesAsync()
{
    Task<byte[]> readBytesTask = Task.Run(() =>
    {
        byte[] bytes;

        do
        {
            bytes = ReadBytes();
        } while (bytes == null);

        return bytes;
    });

    return readBytesTask;
}

private byte[] ReadBytes()
{
   byte[] readBytes = _usbSdk.ReadBytes(); //100ms timeout (returns null if no bytes read)
   return readBytes;
}

推荐答案

我很好,这里只有几个建议:

Looks ok to me, just few suggestions here:

private async Task ListenForUsbMessagesAsync(CancellationToken token)
{
    while (true)
    {
        byte[] readBytes = await ReadBytesAsync();
        Parse(readBytes);
        token.ThrowIfCancellationRequested();
    }
}

其他地方,例如在WPF Window .ctor中存储此

Somewhere else, like in WPF Window .ctor store this

var tokenSource = new System.Threading.CancellationTokenSource();

最后像这样调用您的函数

Finally call your function like this

 private void _connectUsbButton_Click(object sender, RoutedEventArgs e)
 {
    ListenForUsbMessagesAsync(tokenSource.Token);
 }

通过这种方式,您可以随时通过致电取消任务

This way you can cancel your task in any moment by calling

tokenSource.Cancel()

或者,如果您不想使用任务",则可以生成一个新线程并传递

Alternatively, if you don't want to use Tasks, you can spawn a new Thread and pass in the Dispatcher object. In this way, the newly created Thread can fire stuff onto the UI Thread safely.

这篇关于使用任务进行连续轮询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆