如何序列化异步/等待? [英] How to serialize async/await?

查看:102
本文介绍了如何序列化异步/等待?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们假设我有这个简单的片断:

Let's suppose I have this simple snippet:

async void button_Click(object sender, RoutedEventArgs e)
{
    await Task.Factory.StartNew(() =>
    {
        Console.WriteLine("start");
        Thread.Sleep(5000);
        Console.WriteLine("end");
    });
}

显然,每次我按下这个按钮一个新的任务甚至开始时previous任务仍然运行。我如何将推迟任何新的任务,直到所有previous任务已经完成?

Obviously, everytime I push that button a new task is started even when a previous task still runs. How would I postpone any new task until all previous tasks have finished?

更多的细节:

在上面的例子中,每一个新的任务是相同的前任务。然而,在原有范围内的任务序列事项:参数可能会改变(我可以模拟,它通过使用 DateTime.Now.Ticks )。
任务应该他们是注册的顺序执行。特异性地,我的程序会跟一个串行设备。我以前有一个后台线程利用 BlockingCollection 做到了这一点。不过,这一次有一个严格的请求/响应协议,我想使用异步/的await,如果它是可能的。

In the example above, each new task is identical to the task before. However, in the original context the sequence of tasks matters: Parameters may change (I could "simulate" it by using DateTime.Now.Ticks). The tasks should be executed in the order they are "registered". Specificly, my program will talk to a serial device. I've done this before with a background thread utilizing a BlockingCollection. However, this time there's a strict request/response-protocol and I'd like to use async/await if it is possible.

可能的解决方法:

我可以想象创建任务并将它们存储在一个列表中。但我怎么就要求执行任务吗?或者我应该回到我之前已经使用了基于线程的解决方案?

I could imagine creating tasks and storing them in a list. But how would I execute the tasks with respect to the requirements? Or should I return to the thread-based solution I have used before?

推荐答案

您可以等待一个 SemaphoreSlim 异步和释放,一旦任务完成。不要忘了信号灯initialcount配置为 1

You could wait on a SemaphoreSlim asynchronously and release it once the job is done. Don't forget to configure the semaphore initialcount to 1.

private static SemaphoreSlim semaphore = new SemaphoreSlim(1);

private async static void DoSomethingAsync()
{
     await semaphore.WaitAsync();
     try
     {
        await Task.Factory.StartNew(() =>
        {
            Console.WriteLine("start");
            Thread.Sleep(5000);
            Console.WriteLine("end");
        });
     }
     finally
     {
        semaphore.Release();
     }
}

private static void Main(string[] args)
{
    DoSomethingAsync();
    DoSomethingAsync();
    Console.Read();
}

这篇关于如何序列化异步/等待?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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