-2

After spending far too much time trying to sort out async/await hell we're trying to get a standard for when we have to call an async method on a library we don't control and where there is no non-async method provided and get async out of our code all together.

I don't want a discussion of the merits of this I'm sure that for some people async/await works, just a foolproof way of calling any async method and not getting deadlocks etc.

Does

public someObject SomeFunction(string parameter)
{
    return Task.Run(() => 3rdPartyLib.SomeFunctionAsync(parameter)).Result;
}

and

public void SomeMethod()
{
    return Task.Run(() => 3rdPartyLib.SomeMethodAsync()).Wait;
}

Do the job? Do I need to configureAwait(false)? Will exceptions work normally?

dibs487
  • 1,294
  • 4
  • 21
  • 36
  • 5
    The answer is there is none. Literally anything you do is going to have potential problems. That's why you need to not put yourself in that position in the first place. If there was a simple foolproof solution that always worked you wouldn't constantly have people telling you why you shouldn't be doing this, as there'd be no need. – Servy Feb 27 '19 at 16:45
  • @Servy well I agree and I've tried to find alternative libraries that have synchronous methods – dibs487 Feb 28 '19 at 09:25

1 Answers1

6

Well, writing synchronous wrappers for asynchronous methods is an antipattern, too.

That said, there are a variety of hacks covered in my Brownfield Async article. The one you propose - the "thread pool hack" - will work unless the third party library requires use of the current context. E.g., if it is a method that expects to run in a scenario where it has access to UI controls, or if it expects to have HttpContext.Current. Most libraries do not require this, so this hack would work for them.

There is no hack that works everywhere, in all scenarios.

You do not need ConfigureAwait(false). There is no await to configure.

For exceptions, you should use GetAwaiter().GetResult() instead of Result and Wait(). That prevents exceptions from being wrapped in AggregateException.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
  • 1
    Stephen, I salute you for still being sane and productive after having to repeat yourself so many times on this point :D – Dai Feb 27 '19 at 16:55
  • 1
    I always through sync wrappers were good until I read the link you referenced before. Probably saved me from some many *hard* bugs. Good link – Jlalonde Feb 27 '19 at 16:55
  • Thanks very much for that brownfield async article, very good, seeing as we're almost never IO bound and very CPU bound I suspect that's why we've got into problems it's a shame that so much of .net is forcing async/await – dibs487 Feb 28 '19 at 09:23
  • @dibs487: `async` wasn't intended for CPU-bound code; it would cause problems if devs tried to use `async` where it wasn't needed. `async` works beautifully for I/O, but mixing with CPU-bound takes some care. I have a blog series on [`Task.Run` etiquette](https://blog.stephencleary.com/2013/10/taskrun-etiquette-and-proper-usage.html) that partially untangles this. – Stephen Cleary Feb 28 '19 at 15:04