假设我有这个简单的片段:
async void button_Click(object sender, RoutedEventArgs e)
{
await Task.Factory.StartNew(() =>
{
Console.WriteLine("start");
Thread.Sleep(5000);
Console.WriteLine("end");
});
}
显然,每次我按下该按钮时,都会启动一个新任务,即使之前的任务仍在运行。我如何将任何新任务推迟到所有以前的任务完成之前?
更多细节:
在上面的示例中,每个新任务都与之前的任务相同。然而,在原始上下文中,任务的顺序很重要:参数可能会改变(我可以使用 DateTime.Now.Ticks
来“模拟”它)。
任务应该按照它们“注册”的顺序执行。具体来说,我的程序将与串行设备通信。我之前使用 BlockingCollection
在后台线程中完成过此操作。然而,这次有一个严格的请求/响应协议(protocol),如果可能的话,我想使用异步/等待。
可能的解决方案:
我可以想象创建任务并将它们存储在列表中。但是我将如何根据要求执行任务呢?还是应该回到之前使用的基于线程的解决方案?
最佳答案
我建议使用 SemaphoreSlim
进行同步。但是,您想 avoid Task.Factory.StartNew
(正如我在我的博客上解释的那样),还有 definitely avoid async void
(正如我在 MSDN 文章中解释的那样)。
private SemaphoreSlim _mutex = new SemaphoreSlim(1);
async void button_Click(object sender, RoutedEventArgs e)
{
await Task.Run(async () =>
{
await _mutex.WaitAsync();
try
{
Console.WriteLine("start");
Thread.Sleep(5000);
Console.WriteLine("end");
}
finally
{
_mutex.Release();
}
});
}
关于c# - 如何序列化异步/等待?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21163136/