2013-07-31 33 views
7

如果超過2分鐘,我需要取消UpdateDatabase()函數。我試過cancellationtokens定時器但我無法解決這個問題(找不到任何合適的例子)。取消具有超時的靜態異步函數

你能幫我解決嗎?

App.xaml.cs

protected override async void OnLaunched(LaunchActivatedEventArgs args) 
{ 
    await PerformDataFetch(); 
} 

internal async Task PerformDataFetch() 
{ 
    await LocalStorage.UpdateDatabase(); 
} 

LocalStorage.cs

public async static Task<bool> UpdateDatabase() 
{ 
    await ..// DOWNLOAD FILES 
    await ..// CHECK FILES 
    await ..// RUN CONTROLES 
} 

根據答案編輯我的班。

App.xaml.cs保持不變。 UpdateDatabase()編輯和新方法RunUpdate()在LocalStorage.cs添加

public static async Task UpdateDatabase() 
{ 
    CancellationTokenSource source = new CancellationTokenSource(); 
    source.CancelAfter(TimeSpan.FromSeconds(30)); // how much time has the update process 
    Task<int> task = Task.Run(() => RunUpdate(source.Token), source.Token); 

    await task; 
} 

private static async Task<int> RunUpdate(CancellationToken cancellationToken) 
{ 
    cancellationToken.ThrowIfCancellationRequested(); 
    await ..// DOWNLOAD FILES 
    cancellationToken.ThrowIfCancellationRequested(); 
    await ..// CHECK FILES 
    cancellationToken.ThrowIfCancellationRequested(); 
    await ..// RUN CONTROLES 
} 

我知道這是不是唯一的方式,可能會更好,但好點啓動像我這樣的新手。

+0

你可以使用WaitOne的,如果你能等到通話與超時完成,或者需要實現自己的定時器..請參閱http://stackoverflow.com/questions/5973342/how-to-handle-timeout-in-async-socket –

回答

5

您需要將CancellationToken傳遞給UpdateDatabase函數,並在每次等待後通過調用ThrowIfCancellationRequested來檢查令牌。見this

+2

此外,將令牌傳遞給您調用的每個需要令牌的方法。 –

1

你可以試試這個:

const int millisecondsTimeout = 2500; 
Task updateDatabase = LocalStorage.UpdateDatabase(); 
if (await Task.WhenAny(updateDatabase, Task.Delay(millisecondsTimeout)) == updateDatabase) 
{ 
    //code 
} 
else 
{ 
    //code 
}