Call method which accepts an Action parameter synchronously - c#

I am working with a library for which I do not have the source, and as such I can't decorate it with the async keyword and do things like await a Task (at least I don't know how to do that). It exposes a method which returns an object (I'll call it "answer") and takes an integer, and a parameter of type Action where I retrieve that answer. How can I wait for answer to get populated before my code continues?
Object answer = null;
remoteLibrary.remoteMethod(42, x =>
{
answer = x.Value; //This might take a few seconds
});
//I want to do something here with "answer" AFTER it has been populated

You need a synchronization construct. And since this can take a few seconds it would be a waste to use a synchronous (blocking) one so I suggest an asynchronous one like TaskCompletionSource:
var tcs = new TaskCompletionSource<object>();
remoteLibrary.remoteMethod(42, x =>
{
tcs.SetResult(x.Value);
});
var answer = await tcs.Task;
// use answer
The TaskCompletionSource exposes a task that you can await that wouldn't complete until you call SetResult (or SetCanceled, SetException). When it completes you get the result you set in SetResult so you don't need the dummy variable anymore.

Related

Does it make sense to call only one `async` method and `await` for it in another `async` method?

Does it make sense to call only one async private method and await for it in another async method?
Example:
private async Task<string> ReadMyFileAsync()
{
var streamReader = new StreamReader(#"c:\myFile.txt")
return await streamReader.ReadToEndAsync(); // <-- Does it make sense for me here to await for only onething, while the caller of the method ReadMyFileAsync is already an async method?
// By ignoring that the stream should be disposed...
}
private string ReadMyFile()
{
var streamReader = new StreamReader(#"c:\myFile.txt")
return streamReader.ReadToEnd();
// By ignoring that the stream should be disposed...
}
public async void OnFileChangedHandler()
{
// Some work...
var myText = await ReadMyFileAsync(); <-- Does it make any difference whether I called `await ReadMyFileAsync()` or `ReadMyFile()`?
var someThingElse = await SomeThingElse(...);
// Some work...
}
In the scenario above, what I guess, even if the method ReadMyFileAsync was called in its syncronous version (without using async and by using ReadToEnd() instead of await ReadToEndAsync()), it will keep acting the same, because the caller method is an async method. Which means in my opinion, this will make sense only if I am trying to read multiple files in paralell (see the following as example), is that right?
private async Task<string> ReadMyFileAsync() // <-- This makes sense for me
{
var streamReader1 = new StreamReader(#"c:\myFile1.txt");
var streamReader2 = new StreamReader(#"c:\myFile2.txt");
var streamReader3 = new StreamReader(#"c:\myFile3.txt");
var myText1Task = streamReader1.ReadToEndAsync();
var myText2Task = streamReader2.ReadToEndAsync();
var myText3Task = streamReader3.ReadToEndAsync();
return await myText1Task + await myText2Task + await myText3Task;
// By ignoring that the streams should be disposed...
}
So the question is simply, in the first block of code, does it make any difference whether I called ReadMyFileAsync or ReadMyFile?
Update: The whole question simplified is:
If I am going to await for the async method ReadMyFileAsync inside my async method OnFileChangedHandler, why would I use ReadMyFileAsync over ReadMyFile?
It depends. If you really only call one other method and you have no side effects, then you could just return the Task instead of awaiting it and returning the result wrapped in a task.
However, even in your example, you have side effects. You need to .Dispose something and you need to know when to do that. So you cannot just return the task, you need to wait until it's finished, then dispose your resources and then return the result of the finished task. Since it's "not that simple" even in your own boiled down example, the answer is: it does make sense. You have to decide case-by-case.
Sometimes you can just pass the task along, then the method does not need to be async at all, it just needs to return a Task and sometimes you need to do things based on the timing of tasks (i.e. do this only after that other thing is finished) and then you need to use async methods because you want to await results.
Yes, you should prefer async methods over sync because async methods doesn't block the executing thread. In UI apps it means that UI won't freeze. In Server apps it means that your server will be able to run more concurrent work without starving the threads.

Is there a built-in way to have an async method fire an event with the return data when it completes?

Let's say I've created a library with the following async method:
public async Task<string> MyAsyncMethod()
{
// Do stuff
return someString;
}
Now let's say I want the app developer to be able to call this method in a typical fire-and-forget fashion, but then consume an event with the return data when the method completes.
If I were to do this manually, it might look something like this:
public async Task<string> MyAsyncMethod()
{
// Do stuff
// Fire the success event
MyEvent?.Invoke(this, new MyEventArgs { Result = someString });
return someString;
}
...
// Use this callback method to consume the event
public void C_MyAsyncMethodHasCompleted(object sender, MyEventArgs e)
{
Console.WriteLine("Async method has completed with return value: " + e.Result);
}
Here's my question: Is it a waste of time to do it like this? I.e. is there some simpler, built-in thing with C# and/or .NET that already does this?
I mainly just want to make sure I'm not reinventing the wheel with this approach.
I want the app developer to be able to call this method in a typical fire-and-forget fashion, but then consume an event with the return data when the method completes.
I think you might be over-complicating things. I think you can ignore this requirement and just let the consumer deal with it.
In it's simplest form, let's say the consumer wants to start this method, go do something else while waiting, then come back to the result later. They can do something like this:
var myTask = MyAsyncMethod();
// The method starts running and returns a Task<string> when it hits the first await
// (when it starts waiting for whatever I/O request)
DoOtherStuff();
//Now I'm ready for the result, so I await:
var theString = await myTask;
DoSomethingWith(theString);
Likewise, they could store a reference to the Task<string> however they want (pass it to another method, etc.) and only await it when they're ready to use the result.
Or they can use ContinueWith as Theodor suggests (but that has some caveats, like how exceptions are handled). Either way, you, as the author of this library, don't need to worry about it.
Maybe you are searching for the ContinueWith method? The caller can create an "event" by chaining a continuation to the task:
Task<string> task = MyAsyncMethod();
_ = task.ContinueWith(_ => { /* Event handler */ }, TaskScheduler.Default);

Handle result returned by async call within async method

Imagine this is a method performing a DB query and returning a result, which in case of null is replaced with a default value (Null object pattern).
public ResultObj Get()
{
var result = dbContext.GetSomeResult();
return result ?? ResultObj.NullValue;
}
Imagine this DB query is a long-running process, so I would use async/await to execute this process in a separate thread. Suppose that the dbContext.GetSomeResultAsync() method is available.
How can be this method converted in an asynchronous one so that I can write something like this?
var resultTask = GetAsync();
var otherResultTask = GetSomethingElseAsync();
Task.WaitAll(resultTask, otherResultTask);
var myResult = resultTask.Result;
var myOtherResult = otherResultTask.Result;
I tried this solution.
public async Task<ResultObj> GetAsync()
{
var result = await dbContext.GetSomeResultAsync();
return result ?? ResultObj.NullValue;
}
First, I'm wondering why this code compiles: why can I return ResultObj when Task<ResultObj> is expected?
Second, this code predictably results in a deadlock, as clearly explained by the great number of resources about async deadlocks anti-patterns. The deadlock can be prevented by using .ConfigureAwait(false) method after the async call. Is this the right way to go? Are there any hidden drawbacks in this case? Is it a general rule?
I also tried this.
public async Task<ResultObj> GetAsync()
{
return await Task.Run(() => {
var result = dbContext.GetSomeResult();
return result ?? ResultObj.NullValue;
});
}
This results in a deadlock, too. This time I cannot even figure out why.
Edit: possible solution
Finally, after having read this, I found a solution to my problem.
My generic query wrapper method is like this.
public async Task<ResultObj> GetAsync()
{
var result = await dbContext.GetSomeResultAsync();
return result ?? ResultObj.NullValue;
}
On calling method, I use this pattern.
public async Task<CollectedResults> CollectAsync()
{
var resultTask = GetAsync();
var otherResultTask = GetSomethingElseAsync();
//here both queries are being executed.
//...in the while, optionally, here some other synchronous actions
//then, await results
var result = await resultTask;
var otherResult = await otherResultTask;
//here process collected results and return
return new CollectedResults(...);
}
It is worth mentioning that the above code, wrapped in a domain class, is called by a Controller action. In order for this to work I had to make async the methods all the way up, until Controller action, which now appears as follows.
public async Task<CollectedResults> Get()
{
return await resultsCollector.CollectAsync();
}
This way, deadlock doesn't happen anymore and execution time greatly improves with respect to the synchronous version.
I don't know if this is the canonical way of executing parallel queries. But it works and I don't see particular pitfalls in the code.
First of all, regarding :
so I would use async/await to execute this process in a separate thread.
There is no new thread created when we use async and await
Secondly:
why can I return ResultObj when Task is expected?
the Task<TResult> as return type of method tells that it returns a Task of type TResult but we need to return object of type that TResult back from it so the method can be awaited and when using Task<TResult> as reutrn type we should be using async and await to do the work.
Lastly:
this code predictably results in a deadlock
You are using async keyword with method signatures and also await the next async method call being done from within the method. So apparently it looks like the code in first example you have posted shouldn't be deadlocked, if the method GetSomeResultAsync you are consuming is really a async method and is properly implemented.
I suggest to study more about the async await before getting in to it, following is a good article to start with:
https://blog.stephencleary.com/2012/02/async-and-await.html

Where is the return statment for the Task object?

The following code compiles and runs well. But where is the return statement for the Consumer() and Producer() methods?
class Program
{
static BufferBlock<Int32> m_buffer = new BufferBlock<int>(
new DataflowBlockOptions { BoundedCapacity = 10 });
public static async Task Producer() <----- How is a Task object returned?
{
while (true)
{
await m_buffer.SendAsync<Int32>(DateTime.Now.Second);
Thread.Sleep(1000);
}
}
public static async Task Consumer() <----- How is a Task object returned?
{
while (true)
{
Int32 n = await m_buffer.ReceiveAsync<Int32>();
Console.WriteLine(n);
}
}
static void Main(string[] args)
{
Task.WaitAll(Consumer(), Producer());
}
}
While your question states the obvious - the code compiles - and the other answers try to explain-by-example, I think the answer is best described in the following two articles:
"Above-the-surface" answer - full article is here: http://msdn.microsoft.com/en-us/magazine/hh456401.aspx
[...] C# and Visual Basic [...] giving enough hints to the compilers
to build the necessary mechanisms for you behind the scenes. The
solution has two parts: one in the type system, and one in the
language.
The CLR 4 release defined the type Task [...] to represent the
concept of “some work that’s going to produce a result of type T in
the future.” The concept of “work that will complete in the future but
returns no result” is represented by the non-generic Task type.
Precisely how the result of type T is going to be produced in the
future is an implementation detail of a particular task; [...]
The language half of the solution is the new await keyword. A regular
method call means “remember what you’re doing, run this method until
it’s completely finished, and then pick up where you left off, now
knowing the result of the method.” An await expression, in contrast,
means “evaluate this expression to obtain an object representing work
that will in the future produce a result. Sign up the remainder of the
current method as the callback associated with the continuation of
that task. Once the task is produced and the callback is signed up,
immediately return control to my caller.”
2.The under-the-hood explanation is found here: http://msdn.microsoft.com/en-us/magazine/hh456403.aspx
[...] Visual Basic and C# [...] let you express discontinuous
sequential code. [...] When the Visual Basic or C# compiler gets hold
of an asynchronous method, it mangles it quite a bit during
compilation: the discontinuity of the method is not directly supported
by the underlying runtime and must be emulated by the compiler. So
instead of you having to pull the method apart into bits, the compiler
does it for you. [...]
The compiler turns your asynchronous method into a statemachine. The
state machine keeps track of where you are in the execution and what
your local state is. [...]
Asynchronous methods produce Tasks. More specifically, an asynchronous
method returns an instance of one of the types Task or Task from
System.Threading.Tasks, and that instance is automatically generated.
It doesn’t have to be (and can’t be) supplied by the user code. [...]
From the compiler’s point of view, producing Tasks is the easy part.
It relies on a framework-supplied notion of a Task builder, found in
System.Runtime.CompilerServices [...] The builder lets the compiler
obtain a Task, and then lets it complete the Task with a result or an
Exception. [...] Task builders are special helper types meant only for
compiler consumption. [...]
[...] build up a state machine around the production and consumption
of the Tasks. Essentially, all the user logic from the original method
is put into the resumption delegate, but the declarations of locals
are lifted out so they can survive multiple invocations. Furthermore,
a state variable is introduced to track how far things have gotten,
and the user logic in the resumption delegate is wrapped in a big
switch that looks at the state and jumps to a corresponding label. So
whenever resumption is called, it will jump right back to where it
left off the last time.
when the method has no return statement its return type is Task. Have a look at the MSDN page of Async Await
Async methods have three possible return types: Task<TResult>, Task, void
if you need a Task you must specify the return statement. Taken from the MSDN page:
// TASK<T> EXAMPLE
async Task<int> TaskOfT_MethodAsync()
{
// The body of the method is expected to contain an awaited asynchronous
// call.
// Task.FromResult is a placeholder for actual work that returns a string.
var today = await Task.FromResult<string>(DateTime.Now.DayOfWeek.ToString());
// The method then can process the result in some way.
int leisureHours;
if (today.First() == 'S')
leisureHours = 16;
else
leisureHours = 5;
// Because the return statement specifies an operand of type int, the
// method must have a return type of Task<int>.
return leisureHours;
}
async keyword kind of tells compiler that the method body should be used as a Task body. In simple way we can say that these are equivalents to your examples:
public static Task Producer() <----- How is a Task object returned?
{
return Task.Run(() =>
{
while (true)
{
m_buffer.SendAsync<Int32>(DateTime.Now.Second).Wait();
Thread.Sleep(1000);
}
});
}
public static Task Consumer() <----- How is a Task object returned?
{
return Task.Run(() =>
{
while (true)
{
Int32 n = m_buffer.ReceiveAsync<Int32>().Wait();
Console.WriteLine(n);
}
});
}
Of course the compiled result of your methods will be completely different from my examples, because compiler smart enough and it can generate code in such way, so some of the lines in your method will be invoked on the context (thread), which calls the method and some of them on the background context. And this is actually why Thread.Sleep(1000); is not recommended in the body of async methods, because this code can be invoked on the thread, which calls this method. Task has equivalent which can replace Thread.Sleep(1000); the equivalent await Task.Delay(1000), which will be invoked on background thread. As you can see await keyword guaranties you that this call will be invoked on the background context and will not block the caller context.
Let's take a look on one more example:
async Task Test1()
{
int a = 0; // Will be called on the called thread.
int b = await this.GetValueAsync(); // Will be called on background thread
int c = GetC(); // Method execution will come back to the called thread again on this line.
int d = await this.GetValueAsync(); // Going again to background thread
}
So we can say that this will be generated code:
Task Test1()
{
int a = 0; // Will be called on the called thread.
vat syncContext = Task.GetCurrentSynchronizationContext(); // This will help us go back to called thread
return Task.Run(() =>
{
// We already on background task, so we safe here to wait tasks
var bTask = this.GetValueAsync();
bTask.Wait();
int b = bTask.Result;
// syncContext helps us to invoke something on main thread
// because 'int c = 1;' probably was expected to be called on
// the caller thread
var cTask = Task.Run(() => return GetC(), syncContext);
cTask.Wait();
int c = cTask.Result;
// This one was with 'await' - calling without syncContext,
// not on the thread, which calls our method.
var dTask = this.GetValueAsync();
dTask.Wait();
int d = dTask.Result;
});
}
Again, this is not the same code which you will get from compiler, but it should just give you some idea how this works. If you really want to take a look on what will be in the produced library, use for example IlSpy to take a look on generated code.
Also I really recommend to read this article Best Practices in Asynchronous Programming
That's exactly what the async keyword means. It takes a method and (usually) converts it to a Task returning method. If the normal method would have the return type of void, the async method will have Task. If the return type would be some other T, the new return type will be Task<T>.
For example, to download an process some data synchronously, you could write something like:
Foo GetFoo()
{
string s = DownloadFoo();
Foo foo = ParseFoo(s);
return foo;
}
The asynchronous version would then look like this:
Task<Foo> GetFoo()
{
string s = await DownloadFoo();
Foo foo = ParseFoo(s);
return foo;
}
Notice that the return type changed from Foo to Task<Foo>, but you're still returning just Foo. And similarly with void-returning methods: since they don't have to contain a return statement, async Task (without any <T>) methods also don't.
The Task object is constructed by the compiler-generated code, so you don't have to do that.

How to handle return values in async function

When working on data APIs which use async rest calls (I am using RestSharp.Portable), what is the best way to handle return values? Since async function can only return a Task or Task ... but the caller has no way to getting back to the return value ... how would the API return data back to the caller? Global properties?
From what I have read so far, it appears that callback functions are the only way to interact with Response Data?
Take the following method for example; previously I was not using async Rest library and was able to return a value but after converting it to use RestSharp.Portable, I dont see a way to return the value:
public async Task<EntityResourceDescriptor> GetEntityDescriptor(string entityType)
{
TaskCompletionSource<EntityResourceDescriptor> tcs = new TaskCompletionSource<EntityResourceDescriptor>();
var req = new RestRequest("/qcbin/rest/domains/{domain}/projects/{project}/customization/entities/{entityType}");
AddDomainAndProject(req);
req.AddParameter("entityType", entityType, ParameterType.UrlSegment);
client.ExecuteAsync<EntityResourceDescriptor>(req, (res) =>
{
if (res.ResponseStatus == ResponseStatus.Error)
{
tcs.TrySetException(res.ErrorException);
}
else
{
tcs.SetResult(res.Data);
}
}
);
return tcs.Task;
}
Here all I can do is return Task but the caller still has no way to get to the response data or am I missing something obvious? Can the caller subscribe to an event which gets fired at Task.Completed etc.?
I am very fuzzy on this async concept. Are there any examples of writing Portable data APIs?
I think you'll really need to take a step back and read about how to use the async and await keywords. Among other things, you'll need to understand some of the compiler magic that happens behind the scenes when coding async methods.
Here is a good place to start: Asynchronous Programming with Async and Await.
More to your question, the Return Types and Parameters section has this to say:
You specify Task<TResult> as the return type if the method contains a Return (Visual Basic) or return (C#) statement that specifies an operand of type TResult.
It then gives the following code example:
// Signature specifies Task<TResult>
async Task<int> TaskOfTResult_MethodAsync()
{
int hours;
// . . .
// Return statement specifies an integer result.
return hours;
}
Notice how despite the method return type of Task<int>, the return statement simply returns an int, not a Task<int>. That's basically because there is some compiler magic going on that makes this legal only in async methods.
Without wanting to get into all the details, you should also know that the caller of the async method is normally expected to do so using the await keyword, which knows how to deal with the Task or Task<TResult> return values and automatically unwraps the actual expected return value for you in a transparent manner (more compiler magic behind the scenes).
So for the above example, here is one way to call it:
int intValue = await TaskOfTResult_MethodAsync(); // Task<int> is automatically unwrapped to an int by the await keyword when the async method completes.
Or, if you wish to start the async method, perform some other work in the meantime, and then wait for the async method to complete, this can be done like this:
Task<int> t = TaskOfTResult_MethodAsync();
// perform other work here
int intValue = await t; // wait for TaskOfTResult_MethodAsync to complete before continuing.
Hopefully this gives you a general idea of how to pass values back from an async method.
For your specific example, I am not familiar with RestSharp (never used it). But from what little I read, I think you'll want to use client.ExecuteTaskAsync<T>(request) instead of client.ExecuteAsync<T>(request, callback) to better fit in the async-await model.
I'm thinking your method would instead look something like this:
public async Task<EntityResourceDescriptor> GetEntityDescriptor(string entityType)
{
var req = new RestRequest("/qcbin/rest/domains/{domain}/projects/{project}/customization/entities/{entityType}");
AddDomainAndProject(req);
req.AddParameter("entityType", entityType, ParameterType.UrlSegment);
var res = await client.ExecuteTaskAsync<EntityResourceDescriptor>(req);
if (res.ResponseStatus == ResponseStatus.Error)
{
throw new Exception("rethrowing", res.ErrorException);
}
else
{
return res.Data;
}
}
Your calling code would then look like this:
EntityResourceDescriptor erd = await GetEntityDescriptor("entityType");
I hope you manage to get this working. But again, make sure to read the documentation about the async-await style of programming. It's very neat once you wrap your head around the compiler magic that is done for you. But it's so easy to get lost if you don't take the time to really understand how it works.

Categories