【问题标题】:How to cancel async Task after a period of time一段时间后如何取消异步任务
【发布时间】:2012-11-27 14:32:57
【问题描述】:

在我的 Windows Store 应用程序中,我有一个方法

public async static Task InitAds()
{
    Debug.WriteLine("API: Loading Ad images");
    await Task.WhenAll(ads.Select(l => l.Value).Where(l=>l!=null).Select(l => l.StartRotation()));
 }

我用来下载和初始化(下载、解析|项目中的广告。调用时等待这个方法

...
await AdReader.InitAds()
...

问题在于广告服务器有时响应非常缓慢。我想要一个超时时间,比如说这个方法运行 10 秒。如果它没有在这个超时时间内完成,我希望它被杀死并且我的代码继续。

实现这一点的最佳方法是什么?我找到了How to cancel a Task in await?,但它使用了 TaskFactory,当我尝试这种方法并在 Task.Run 中调用我的方法时,它不会等待,代码会继续。

编辑:

StartRotation 也是一个异步方法调用另一个异步方法

public async Task StartRotation(CancellationToken ct)
{
        if (Images.Count == 1)
        {
            await Image.LoadAndSaveImage(ct);
        }

        if (Images.Count <2) return;

        foreach (var img in Images)
        {
            await img.LoadAndSaveImage(ct);
        }

        Delay = Image.Delay;
        DispatcherTimer dt = new DispatcherTimer();
        dt.Interval = TimeSpan.FromMilliseconds(Delay);
        dt.Tick += (s, e) =>
        {
            ++index;
            if (index > Images.Count - 1)
            {
                index = 0;
            }
            Image = Images[index];
        };
        dt.Start();
    }

【问题讨论】:

  • l.StartRotation 的签名是什么?您可以尝试同步实现 StartRotation,将其包装到 TaskFactory.StartNew 中并在其中提供适当的 CancellationToken。
  • 这有什么帮助?它实际上不会取消该方法的执行。

标签: c# microsoft-metro windows-runtime async-await


【解决方案1】:

取消是合作的。您只需将CancellationToken 传递给您的StartRotation

public async static Task InitAds(CancellationToken token)
{
  Debug.WriteLine("API: Loading Ad images");
  await Task.WhenAll(ads.Select(l => l.Value).Where(l=>l!=null).Select(l => l.StartRotation(token)));
}

然后这样称呼它:

var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
await InitAds(cts.Token);

【讨论】:

  • “合作”是指我需要将它传递给我调用的每一个 asyc 方法?如果是这样,如果我使用不采用 CancellationToken 的第三方异步方法怎么办?会不会因为这个不工作?
  • 是的。如果您有一个不采用CancellationTokenasync 方法,则该方法不能被取消。您可以编写一个可以“取消”的包装器(并使其提前返回),但不可取消的 async 方法将继续运行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多