2012-11-27 48 views
0

在我的Windows商店應用後,我有一個方法如何取消異步任務一段時間

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(); 
    } 
+2

【如何取消不取消異步操作?(HTTP://blogs.msdn .com/b/pfxteam/archive/2012/10/05/how-do-i-cancel-non-cancelable-async-operations.aspx) – Servy

+0

l.StartRotation的簽名是什麼?您可以嘗試同步實現StartRotation,將其包裝到TaskFactory.StartNew中並在其中提供適當的CancellationToken。 –

+0

這將如何幫助?它實際上不會取消該方法的執行。 – svick

回答

2

取消是合作。你只需要通過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); 
+0

通過「合作」您是否意味着我需要將它傳遞給每一個asyc方法,我稱之爲方式?如果是這樣,如果我使用不採用CancellationToken的thrid-party異步方法怎麼辦?它會因爲這個而無法工作嗎? –

+2

是的。如果你有一個'async'方法,不需要'CancellationToken',那麼這個方法就不能被取消。您可以編寫一個可以「取消」(並儘早返回)的包裝器,但不可取消的'async'方法將繼續運行。 –