Sometimes I have the need to call an async function from a non-async function and get the result back synchronously. Therefore I wrote the following helper function to be able to do this in one line.
public static T RunSync<T>(Func<Task<T>> taskConstructor)
{
var signal = new ManualResetEventSlim();
T result;
Exception ex = null;
ThreadPool.QueueUserWorkItem(async () =>
{
try
{
var task = taskConstructor();
result = await task.ConfigureAwait(false);
}
catch (Exception iex)
{
ex = iex;
}
finally
{
signal.Set();
}
});
signal.Wait();
if (ex != null)
throw ex;
return result;
}
Is this ok to do or will it behave unexpectedly in some edge cases? I know that writing this kind of async functions in can be tricky and can easily deadlock. That's why I ran it inside a ThreadPool thread which should prevent any kind of deadlock.
I think that this is probably not the most performant way to do it, but preventing deadlocks is more important in my case.
I know that re-throwing an exception is not ideal, but I think this is a compromise I have to make here.