我有这种模式,以防止在先前有机会完成之前调用异步方法。如何最好地防止在完成之前再次运行异步方法?
我的解决方案涉及需要一个标志,然后需要锁定国旗,感觉非常详细。是否有更自然的方式来实现这一点?
public class MyClass
{
private object SyncIsFooRunning = new object();
private bool IsFooRunning { get; set;}
public async Task FooAsync()
{
try
{
lock(SyncIsFooRunning)
{
if(IsFooRunning)
return;
IsFooRunning = true;
}
// Use a semaphore to enforce maximum number of Tasks which are able to run concurrently.
var semaphoreSlim = new SemaphoreSlim(5);
var trackedTasks = new List<Task>();
for(int i = 0; i < 100; i++)
{
await semaphoreSlim.WaitAsync();
trackedTasks.Add(Task.Run(() =>
{
// DoTask();
semaphoreSlim.Release();
}));
}
// Using await makes try/catch/finally possible.
await Task.WhenAll(trackedTasks);
}
finally
{
lock(SyncIsFooRunning)
{
IsFooRunning = false;
}
}
}
}
可以使用'Interlocked.Exchange()'来代替'lock()'。 – SLaks
不要使用'async void'。 – SLaks
@Slaks - Interlocked.Exchange不支持bools。我将代码更改为异步任务,但它不需要任何其他更改。似乎有点奇怪,所有返回类型仍然对任务有效? –