让我们假设我有这个简单的片段:
async void button_Click(object sender, RoutedEventArgs e)
{
await Task.Factory.StartNew(() =>
{
Console.WriteLine("start");
Thread.Sleep(5000);
Console.WriteLine("end");
});
}
Run Code Online (Sandbox Code Playgroud)
显然,每次按下该按钮,即使前一个任务仍在运行,也会启动一个新任务.在所有先前的任务完成之前,我将如何推迟任何新任务?
更多细节:
在上面的示例中,每个新任务都与之前的任务相同.但是,在原始上下文中,任务序列很重要:参数可能会发生变化(我可以通过使用来"模拟"它DateTime.Now.Ticks).任务应按照"注册"的顺序执行.具体来说,我的程序将与串行设备通信.我之前用背景线程利用了一个BlockingCollection.但是,这次有一个严格的请求/响应协议,如果可能,我想使用async/await.
可能的方法:
我可以想象创建任务并将它们存储在列表中.但是,我如何执行与要求相关的任务?或者我应该回到之前使用的基于线程的解决方案?
我正在审查我的同事的一些WPF代码,这是一个基于组件的库,UserControl包含许多async void事件和命令处理程序.这些方法目前不在内部实现任何错误处理.
代码简而言之:
<Window.CommandBindings>
<CommandBinding
Command="ApplicationCommands.New"
Executed="NewCommand_Executed"/>
</Window.CommandBindings>
Run Code Online (Sandbox Code Playgroud)
private async void NewCommand_Executed(object sender, ExecutedRoutedEventArgs e)
{
// do some fake async work (and may throw if timeout < -1)
var timeout = new Random(Environment.TickCount).Next(-100, 100);
await Task.Delay(timeout);
}
Run Code Online (Sandbox Code Playgroud)
抛出异常但未在内部观察到的异常NewCommand_Executed 只能在全局级别上处理(例如,使用AppDomain.CurrentDomain.UnhandledException).显然,这不是一个好主意.
我可以在本地处理异常:
private async void NewCommand_Executed(object sender, ExecutedRoutedEventArgs e)
{
try
{
// do some fake async work (throws if timeout < -1)
var timeout = new …Run Code Online (Sandbox Code Playgroud)