1

I'm having a bit of a brain freeze about calling an async process. I have my void main function, and I want to call an method from a third party dll which is only exists as an async method - I don't care it's async I just want to run it synchronously.

So how do I go about doing this? I had a quick look at How to call asynchronous method from synchronous method in C#? but it seems a little complex, having to worry about contextes etc. This should be easy right?

Thanks Thomas

Community
  • 1
  • 1
friartuck
  • 2,954
  • 4
  • 33
  • 67
  • If you are worried about your sync context I seriously suggest you start plumbing Async into your code. If at any point inside the async code it tries to schedule work on the main thread, you will end up in a deadlock. – Aron Aug 30 '13 at 05:07
  • Not following. Here is my problem. I need my main void function to call a third party dll which returns a List, however this method was built asynchronously, so rather it returns Task>. At the end of the day I want to be able to call it like a normal method and loop through each item in the List and print it to screen. – friartuck Aug 30 '13 at 05:24
  • Async/await wraps up a lot of subtleties that can easily cause deadlocks when mixed with "synchronous" code. The naive approach to converting a async method to a synchronous method is to have the calling thread block until the async process is complete. However any resources that the blocked thread now "owns" is not available until it unblocks. If for example the async process now wants to, say update a progress bar using the main thread, then it would need to wait for the main thread to unblock. However the main thread is waiting for the async process to complete. – Aron Aug 30 '13 at 05:39
  • I think I see what you're getting at. But what should I do in my situation? – friartuck Aug 30 '13 at 05:54

1 Answers1

1

Just grab the returned Task's Result property

var returned = methodCall().Result;

this will block until the task is complete, and then return. If it's already complete it will continue executing normally. I think you're just wanting to call a single method once, synchronously, but just in case, note that if you have multiple calls that you want to happen asynchronously, you need to call them first, then hit the results

var returned1 = methodCall1(); // this is a Task<List<string>>
var returned2 = methodCall2();
var actualValue1 = returned1.Result; // this is the associated List<string>
var actualValue2 = returned2.Result;
MaxK
  • 424
  • 3
  • 9
  • With the second case you have the danger of deadlocking on a resource like sockets. If `methodCalls` each open up a tcp connection we likely would be using a connection pool. Assume a pool of 1, and due to some timing issue methodCall2 ran first, methodCall1 is waiting on the connection pool to be returned. Once methodCall2 gets a response, it is waiting for `.Result` to be called to flush the stream. Result Deadlock. – Aron Aug 30 '13 at 06:52
  • It's certainly plausible yes, but it really depends on what each of them are doing. You have to make a bit of a judgement call depending on what the async functions do (and how much you know about that, of course). I suppose it's much riskier with an external library where you cant trace through that code. – MaxK Aug 30 '13 at 22:12