AndersMad
AndersMad

Reputation: 338

async/await on CacheItemPolicy.UpdateCallback event and other event delegates

How-to: Call await method from a delegate void event method?

Converting (an ASP.NET) app to async is an all in - granted. But what about the places where it is not supported?

var policy = new CacheItemPolicy();
policy.UpdateCallback = CacheEntryUpdateCallback;

void VoidDelegate(CacheEntryUpdateArguments arguments) {
   // need this - but no can't do :(
   await SomeApi.AsyncOnlyMethodAsync(); 
}

Await is not allow there, so what to do? What is the right way of doing this? The question also, applies to event handlers on WebForms like myButton.Commmand += new CommandEventHandler(VoidDelegate)

Is it A:

void VoidDelegate(CacheEntryUpdateArguments arguments) {
   Task.Factory.StartNew(new Func<Task>(async () => {
     await SomeApi.AsyncOnlyMethodAsync();
   })).Unwrap().Wait();
}

This will work but spin up another thread? At least it will not make the thread avail for the pool and the purpose of async here is gone.

Or is this supported B:

async void VoidDelegate(CacheEntryUpdateArguments arguments) {
  await SomeApi.AsyncOnlyMethodAsync();
}

But this is a fire-and-forget - but cache update event needs to fetch the new data before returning result. Same goes for e.g. button command event - page could be completed before the command has finished.

Upvotes: 1

Views: 1228

Answers (1)

Servy
Servy

Reputation: 203830

You can mark any method that returns void, Task, or Task<T> as async. Marking a method as async doesn't change the signature of the method, so you're allowed to simply mark VoidDelegate as async if you want it to await things.

Note that, since you now have an async void method, this will be a fire-and-forget method. When someone invokes the delegate the method will return very quickly, while the asynchronous work continues to happen, and the caller will have no way of knowing when the work finishes, or if it errors.

Upvotes: 2

Related Questions