Отменить статическую асинхронную функцию с тайм-аутом

Мне нужно отменить функцию UpdateDatabase(), если она занимает более 2 минут. Я пробовал токены отмены и таймеры, но мне не удалось решить эту проблему (не удалось найти подходящего примера).

Не могли бы вы помочь мне в этом?

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() редактируется, и в LocalStorage.cs добавляется новый метод RunUpdate():

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
}

Я знаю, что это не единственный способ и мог бы быть лучше, но это хорошая отправная точка для таких новичков, как я.


person Korki Korkig    schedule 31.07.2013    source источник
comment
вы можете использовать WaitOne, если вы можете дождаться завершения вызова с тайм-аутом или вам нужно реализовать свой собственный таймер. См. stackoverflow.com/questions/5973342/   -  person now he who must not be named.    schedule 31.07.2013


Ответы (2)


Вам нужно передать CancellationToken функции UpdateDatabase и проверять токен после каждого ожидания, вызывая ThrowIfCancellationRequested. См. это.

person NeddySpaghetti    schedule 31.07.2013
comment
Кроме того, передайте токен каждому вызываемому вами методу, который принимает токен. - person Stephen Cleary; 31.07.2013

Вы можете попробовать это:

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