如何序列化异步/等待? [英] How to serialize async/await?
问题描述
让我们假设我有这个简单的片断:
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屋!