如何序列化async/await?假设我有这个简单的片段:asyncvoidbutton_Click(objectsender,RoutedEventArgse){awaitTask.Factory.StartNew(()=>{Console.WriteLine("start");Thread.Sleep(5000);Console.WriteLine(“结尾”);});显然,每次按下按钮时,都会启动一个新任务,即使前一个任务仍在运行。我如何将任何新任务推迟到所有以前的任务完成之前?更多细节:在上面的示例中,每个新任务都与前一个任务相同。但是,在原始上下文中,任务序列很重要:参数可能会更改(我可以使用DateTime.Now.Ticks来“模拟”它)。任务应该按照它们被“注册”的顺序执行。具体来说,我的程序将与串行设备通信。在使用BlockingCollection的后台线程之前,我已经这样做了。但是,这次有严格的请求/响应协议,如果可能的话我想使用async/await。可能的方法:我可以想象创建任务并将它们存储在列表中。但是我如何执行与需求相关的任务呢?或者我应该回到我之前使用的基于线程的解决方案吗?您可以在SemaphoreSlim上异步等待并在作业完成时释放它。不要忘记将信号量initialcount配置为1。私有静态SemaphoreSlim信号量=newSemaphoreSlim(1);privateasyncstaticvoidDoSomethingAsync(){awaitsemaphore.WaitAsync();尝试{awaitTask.Factory.StartNew(()=>{Console.WriteLine("start");.Sleep(5000);Console.WriteLine("end");});}最后{semaphore.Release();}}privatestaticvoidMain(string[]args){DoSomethingAsync();DoSomethingAsync();安慰。读();我推荐使用SemaphoreSlim进行同步。但是,您想避免使用Task.Factory.StartNew(如我在我的博客中所解释的那样),并且一定要避免使用asyncvoid(如我在我的MSDN文章中所解释的那样)。私人SemaphoreSlim_mutex=newSemaphoreSlim(1);asyncvoidbutton_Click(objectsender,RoutedEventArgse){awaitTask.Run(async()=>{await_mutex.WaitAsync();try{Console.WriteLine("start");Thread.Sleep(5000);Console.WriteLine("结束");}最后{_mutex.Release();}});如何尝试使用Dataflow.ActionBlock(默认)最大并行度为1。这样您就不必担心任何线程安全/锁定问题。它可能看起来像:...var_block=newActionBlock(asyncb=>{Console.WriteLine("start");awaitTask.Delay(5000);Console.WriteLine("end");});...asyncvoidbutton_Click(objectsender,RoutedEventArgse){await_block.SendAsync(true);您还可以设置ActionBlock来接收Task或Func,然后运行/等待此输入??。这将允许多个操作从不同的来源排队。我可能遗漏了一些东西,但我认为OP的情况不需要SemaphoreSlim。我会按照以下方式进行。基本上,代码只是在继续之前等待任务的前一个挂起实例(为清楚起见,没有异常处理)://当前挂起的任务(最初是一个完成的存根)Task_pendingTask=Task.FromResult(true);asyncvoidbutton_Click(objectsender,RoutedEventArgse){varpreviousTask=_pendingTask;_pendingTask=Task.Run(async()=>{awaitpreviousTask;Console.WriteLine("start");Thread.Sleep(5000);Console.WriteLine("end");});//下面的"await"是可选的,//只有在"_pendingTask"完成时在"button_Click"中有其他事情要做时才需要它//await_pendingTask;}[更新]解决注意,这里是线程安全版本,当button_Click可以同时调用时:以上是C#学习教程:如何序列化async/await?所有分享的内容,如果对你有用,需要了解更多C#学习教程,希望大家多多关注—Task_pendingTask=Task.FromResult(true);对象_pendingTaskLock=新对象();asyncvoidbutton_Click(objectsender,RoutedEventArgse){TaskthisTask;锁(_pendingTaskLock){varpreviousTask=_pendingTask;//注意“Task.Run”lambda不会留在锁中thisTask=Task.Run(async()=>{awaitpreviousTask;Console.WriteLine("start");Thread.Sleep(5000);Console.WriteLine("end");});_pendingTask=这个任务;}等待这个任务;}本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如有转载请注明出处:
