Blazor has a SynchronizationContext because it requires rendering to happen on a single thread.
This becomes a problem if an error occurs in the process of rendering, since we have a sink that synchronously blocks because it can no longer return to the thread which is blocked.
This is a solution to the deadlock, however I am open to discussing it.
The general idea I worked with here was to avoid async void as far as possible - which is why I chose to delegate to a separate processor-thread instead.
I also played around with the idea of having it retry multiple times, but not sure whether we want that for the 0.0001% of cases where discord presumably is down (I think that's the only case where an unhandled exception would occur here)
Another solution would be to keep the exact same code, but add ConfigureAwait(false) for all async calls down the chain but I chose to not do this since we would then be relying on an implementation detail.
Blazor has a SynchronizationContext because it requires rendering to happen on a single thread. This becomes a problem if an error occurs in the process of rendering, since we have a sink that synchronously blocks because it can no longer return to the thread which is blocked.
This is a solution to the deadlock, however I am open to discussing it.
The general idea I worked with here was to avoid
async void
as far as possible - which is why I chose to delegate to a separate processor-thread instead.I also played around with the idea of having it retry multiple times, but not sure whether we want that for the 0.0001% of cases where discord presumably is down (I think that's the only case where an unhandled exception would occur here)
Another solution would be to keep the exact same code, but add
ConfigureAwait(false)
for all async calls down the chain but I chose to not do this since we would then be relying on an implementation detail.