我刚刚选择了async / await,并且我编写了一系列异步方法,每个方法都执行数据库SQL任务并将每个方法绑定到不同的按钮。单击按钮时GUI不会被锁定,所以我认为这很棒。
但是,如果单击每个结果,则所需的结果将是第二个按钮将等待第一个任务完成,依此类推。但是,使用async / await,如果我单击多个按钮,我不保证会先完成。因此,它可能会创建一些不必要的竞争条件,导致SQL查询失败。
是否有类/对象/关键字或我可以使用的东西,而不是让每个异步方法处理单个SQL命令,而是将其添加到队列中,并且只有在添加了某些内容时,才会以某种方式串行处理队列它?
答案 0 :(得分:3)
有很多可能的设计。但我总是喜欢TPL Dataflow。
您可以使用ActionBlock
并将async
个帖子发布到其中,以便按顺序处理:
ActionBlock<Func<Task>> _block = new ActionBlock<Func<Task>>(action => action());
block.Post(async () =>
{
await Task.Delay(1000);
MessageBox.Show("bar");
});
另一种可能的解决方案是在执行SemphoreSlim
操作之前异步等待async
设置为1,以确保一次只能执行一个:
SemaphoreSlim _semaphore = new SemaphoreSlim(1);
_semaphore.WaitAsync()
try
{
await Task.Delay(1000);
MessageBox.Show("bar");
}
finally
{
_semaphore.Release();
}
答案 1 :(得分:0)
我不确定我是否理解这个问题,但是如果你想在执行其他操作之前等待特定任务完成,那么你可以做的就是将你从本地变量或列表中开始的任务放在使用等待你的任务或Task.WaitAll所以此时代码等待任务竞争。如果您提供更多详细信息,我们可以提供更好的解决方案。