Async / Await SemaphoreSlim只是最新的任务

时间:2018-06-15 08:55:17

标签: c# asynchronous async-await

我使用轨迹栏作为形态图像操作的输入值的控件。这个操作需要一段时间,所以我想使用async / await来保持轨迹栏的滚动顺畅。

我做了什么:

private static SemaphoreSlim Sema = new SemaphoreSlim(1,1);
private async void Operation()
{
    if(pictureBox_Image.Image != null)
    {
        await Sema.WaitAsync();
        try
        {
            await Task.Run(() => DoStuff());
        }
        catch{}
        finally
        {
            Sema.Release();
        }
    }
 }

但是这样它仍然可以计算所有轨迹栏值的结果。

如何删除所有等待的任务,因此在完成一个值的计算后,只有最新的任务/轨迹栏值将用于下一次计算?

Excample:

跟踪栏值[0,1,2,3,4,5,6] 计算开始巫婆0 - >完成并显示结果 - > trackbar-value现在是4 - >不能用1,2,3 - >计算只有4。

1 个答案:

答案 0 :(得分:0)

因此,还要为您的方法提供CancellationToken,并在取消时采取相应措施。目前尚不清楚如何调用它,因此通常需要保持在调用站点提供令牌的最新CancellationTokenSource。它应该在下次调用Operation之前取消。

private static SemaphoreSlim Sema = new SemaphoreSlim(1,1);
private async void Operation(CancellationToken ct = default)
{
    if(pictureBox_Image.Image != null)
    {
        await Sema.WaitAsync(ct); //throws if cancelled... will not proceed
        try
        {
            await Task.Run(() => DoStuff(ct)); //DoStuff should be checking this CT too
        }
        catch{}
        finally
        {
            Sema.Release();
        }
    }
 }

...将在您的事件处理程序中使用:

currentCancellationTokenSource.Cancel(); //class property/field
currentCancellationTokenSource.Dispose();
currentCancellationTokenSource = new CancellationTokenSource();
Operation(currentCancellationTokenSource.Token);

这可能会导致您需要处理的OperationCanceledException。