Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cancel a static async function with a timeout

I need to cancel the UpdateDatabase() function if it takes more than 2 minutes. I 've tried cancellationtokens and timers but I couldn't manage to solve this (couldn't find any appropriate example).

Could you please help me on this?

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
}

Edited my classes according to answers.

App.xaml.cs stays as same. UpdateDatabase() is edited and the new method RunUpdate() added in 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
}

I know this is not the only way and could be better but a good point to start for newbies like me.

like image 671
Korki Korkig Avatar asked Jul 31 '13 11:07

Korki Korkig


People also ask

How do I terminate async function?

If you want to cancel an async operation in Node. js, such as an HTTP request, you can now use the built in AbortController and AbortSignal classes. They were originally introduced in the Web Platform APIs, which are implemented by web browsers.

Can an async method be void?

With async void methods, there is no Task object, so any exceptions thrown out of an async void method will be raised directly on the SynchronizationContext that was active when the async void method started. Figure 2 illustrates that exceptions thrown from async void methods can't be caught naturally.

What happens if you dont await an async method?

The call to the async method starts an asynchronous task. However, because no Await operator is applied, the program continues without waiting for the task to complete. In most cases, that behavior isn't expected.

How do I run a task in C#?

To start a task in C#, follow any of the below given ways. Use a delegate to start a task. Task t = new Task(delegate { PrintMessage(); }); t. Start();


2 Answers

You need to pass a CancellationToken to the UpdateDatabase function and check the token after each await by calling ThrowIfCancellationRequested. See this

like image 144
NeddySpaghetti Avatar answered Oct 06 '22 18:10

NeddySpaghetti


You could try this:

const int millisecondsTimeout = 2500;
Task updateDatabase = LocalStorage.UpdateDatabase();
if (await Task.WhenAny(updateDatabase, Task.Delay(millisecondsTimeout)) == updateDatabase)
{
    //code
}
else
{
    //code
}
like image 21
rechandler Avatar answered Oct 06 '22 18:10

rechandler