aspnet / WebHooks

[Archived] Libraries to create and consume web hooks on ASP.NET Core. Project moved to https://github.com/aspnet/AspLabs
Apache License 2.0
627 stars 439 forks source link

An asynchronous module or handler completed while ... #118

Closed yvdh closed 7 years ago

yvdh commented 7 years ago

Using code like in the examples for a WebHookHandler

public override Task ExecuteAsync(string receiver, WebHookHandlerContext context) { // Get the event type
string action = context.Actions.First();

  // Extract the WebHook data as JSON or any other type as you wish
  JObject data = context.GetDataOrDefault<JObject>();

  //Debug.WriteLine("Received event from : " + receiver);
  return Task.FromResult(true);
  }

causes the error: An asynchronous module or handler completed while an asynchronous operation was still pending.

I understand about some of the related issues when using async void, but this is different, or not? Anyway, point is that example code does not work ...

Note that I run the webhookhandler on the same website as the web api, which is useful when testing and debigging. Could this be the cause?

Any insights?

yvdh commented 7 years ago

Hello, I found the solution to this one, and it has nothing to do with webhooks in itself, but rather with ASP.NET and webAPI.

In my WEB API controller I have a static collection of items which use a state engine (Stateless library). One of my API calls triggers a transition on one of the collection items, which uses an event handler to call any webhooks which are registered to listen to item state changes.

Thing is I used the Webhooks library NotifyAllAsync method, and as it is an async method, I used it in an async event handler:

private async void PatientVisitStates_ItemStateChanged(object sender, EventArgs e) { await this.NotifyAllAsync(EventFilter.EventType.PatientVisitStateChange.ToString(),sender); }

Now async void calls seem to cause all kinds of problems, see the numerous posts about it. Taking the event handler away makes the errors go away. Making the event handler synchronous does NOT solve the problem (using wait on NotifyAllAsync), as I first thought (it stops the post from ever returning so it must cause some kind of deadlock).

Still searching ...

HenrikFrystykNielsen commented 7 years ago

Makes sense - thanks!

yvdh commented 7 years ago

It seems this works: HostingEnvironment.QueueBackgroundWorkItem((ct) => this.NotifyAllAsync(EventFilter.EventType.PatientVisitStateChange.ToString(), sender));