Multiple hierarchy of task - c#

I want to call a task which itself call a async method which inturn returna bool value.
I want to do something on the basis of that outcome.
I can get the data on outcome.Result.Result but this does not look good and I wish to have the output in outcome.Result.
I can not figure it out.
Can someone please guide.
private void OnValidated(ValidatedIntergrationEvent evt)
{
var outcome=Task.Factory.StartNew(() => mydata.UpdateValidated());
if (outcome.Result.Result)//This work fine but I think I need something to do so that outcome.Result gives my solution.
{ }
else { }
}
public async Task<bool> UpdateValidated()
{
var result= await Mediator.Send(new ValidatedEvent(this));
return result;
}
public async Task<bool> Handle(ValidatedEvent notification, CancellationToken cancellationToken)
{ //dO WORK
// return Task.FromResult(true);
return true;
}

Since UpdateValidated is already asynchronous, you should just call it directly to execute it. Things like Task.Factory.StartNew or Task.Run offer a way to put synchronous tasks on a new thread so that they can run asynchronously. So you should just call it directly:
private void OnValidated(ValidatedIntergrationEvent evt)
{
var outcome = mydata.UpdateValidated()
// Note: this WILL block, regardless of how you call the async function
var result = outcome.Result;
}
You should try to avoid using .Result though, as this will block synchronous functions until the asynchronous result is ready, and may even cause deadlocks. If the OnValidated is a standard event handler, you could make it asynchronous instead and await your task:
private async void OnValidated(ValidatedIntergrationEvent evt)
{
var result = await mydata.UpdateValidated()
}
But this make this event handler fire and forget which can be dangerous. So you should really try to change your code that you are truly running asynchronously when calling asynchronous code.
Finally, note that you can force the asynchronous task onto a separate thread using Task.Run. This is useful when the asynchronous call also does a lot on the CPU:
var outcome = Task.Run(() => mydata.UpdateValidated());
This looks very similar to your Task.Factory.StartNew() call but returns only a Task<bool> instead of your Task<Task<bool>>. This is because Task.Run has an overload that explicitly allows you to call asynchronous methods which makes Task.Run just pass on the result.

Related

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);

Passing a task as parameter

I am not sure whether this is possible, so here me out:
I have a sequence of action to perform multiple
async Task MethodA(...)
{
// some code
// a call to specific Async IO bound method
// some code
}
there are also MethodB(), MethodC(), etc, and all of the have exactly the same code, except for the call to specific Async IO bound method. I am trying to find a way to pass a task pointer to a method, so that we can execute it later in a Method().
What i am currently doing is this:
private async Task Method(Func<Task<Entity>> func)
{
// some code
var a = await task.Run(func);
// some code
}
var task = async () => await CallToIOBoundTask(params);
Method(task);
This code, however, pulls a new thread each time, which is not required for IO bound task, and should be avoided.
So, is there a way to refactor the code so that no ThreadPool thread is used? A goal is to have a code like this:
private async Task Method(Task<Entity> task)
{
// some code
var a = await task;
// some code
}
It is also important to mention that different IO calls have different method signatures. Also, a task can start to execute only in Method() body, and not before.
Of course, simply invoke the func, get back a task, and await it:
async Task Method(Func<Task<Entity>> func)
{
// some code
var a = await func();
// some code
}
Also, when you're sending that lambda expression, since all it's doing is calling an async method which in itself returns a task, it doesn't need to be async in itself:
Method(() => CallToIOBoundTask(params));
That's fine as long as all these calls return Task<Entity>. If not, you can only use Task (which means starting the operation and awaiting its completion) and you won't be able to use the result.

Safe to run async delegate in synchronous method on UI?

If I have an application with a synchronous method, is it safe to call an async method as shown below on a UI thread or is there an issue or potential deadlock situation? I know that calling Wait will obviously cause issues, but I feel like this may work out alright.
public void MyMainMethod(){
var getResult = Task.Run(async () => { await getResultAsync(); }).Result;
myLabel.Text = getResult;
}
I can successfully run on a UI thread without issue, but I feel as if I may be missing something. I understand that I could use a Task and ContinueWith, but in this example, I would want to wait for the result of the async method before exiting the synchronous method.
Update / Clarification
In the example above, let's assume that the MyMainMethod is an overridden method or a property, etc. and cannot be modified to be async.
Let's look at your code:
public void MyMainMethod(){
var getResult = Task.Run(async () => { await getResultAsync(); }).Result;
myLabel.Text = getResult;
}
Regardless of what's taking place inside getResultAsync, this code is blocking the UI thread when it calls task.Result. In most cases, this is already wrong.
Further, the fact that your getResultAsync is async suggests there's already an async operation inside it. There is no reason to wrap it with Task.Run, unless you perform a mix of CPU- and IO- bound tasks inside getResultAsync. Even then, it may not be necessary (see this for more details).
You can control the await continuation context inside getResultAsync with ConfiureAwait(false), and should do so to avoid deadlocks and redundant context switches, where possible.
So, the code can be reduced to:
public void MyMainMethod(){
var getResult = getResultAsync().Result;
myLabel.Text = getResult;
}
As is, it still blocks the UI. To avoid blocking, you need to make it async. See Async All the Way from Best Practices in Asynchronous Programming by Stephen Cleary.
If it cannot be modified to be async (as clarified in the update to your question), then the above is the best you can get. Indeed, it still may cause a deadlock, depending on what's going on inside getResultAsync, with out without Task.Run. To avoid deadlocks, you should not attempt to access the UI thread with a synchronous call like control.Invoke inside getResultAsync, or await any tasks scheduled on the UI thread with TaskScheduler.FromCurrentSynchronizationContext.
However, usually it is possible and desirable to re-factor the code like this into an async version:
public async Task MyMainMethod(){
var getResult = await getResultAsync();
myLabel.Text = getResult;
}
You would be calling it from a top-level entry point of your app, like a UI event handler:
async void Button_Click(object sender, EventArg e)
{
try
{
await MyMainMethod();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
it better to call your ui update through dispatcher.
Task task = LoadTask();
task.ContinueWith(t =>
Dispatcher.BeginInvoke(() => UpdateUI()));
public async Task LoadTask()
{
Task getdata =
Task.Factory.StartNew(() =>
{
Sleep(3000);
});
await getdata;
return;
}

Looking for guidance to understand how asynchronous Programming with Async and Await works

i go through a msdn sample code where a function is called when button is clicked and when routine is called then Await keyword is used and function has async keyword used.
private async void StartButton_Click(object sender, RoutedEventArgs e)
{
int contentLength = await AccessTheWebAsync();
resultsTextBox.Text +=
String.Format("\r\nLength of the downloaded string: {0}.\r\n", contentLength);
}
async Task<int> AccessTheWebAsync()
{
HttpClient client = new HttpClient();
Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");
DoIndependentWork();
string urlContents = await getStringTask;
return urlContents.Length;
}
void DoIndependentWork()
{
resultsTextBox.Text += "Working . . . . . . .\r\n";
}
When AccessTheWebAsync is called then await keyword is used, what does it mean?
When this function AccessTheWebAsync() will be executing then DoIndependentWork() function is called and i guess here control will be waiting until this function DoIndependentWork() is finished. Am I right?
again there is another statement called
string urlContents = await getStringTask;
why they use here await. if we do not use await here then what would happen?
Please guide me to understand the code that how it is working.
I have an intro blog post here, and the MSDN docs are also extremely good.
You can think of await as "pausing" the method (without blocking the thread) until the awaitable operation completes. When this happens, it returns a task that is not completed to the calling method, so it also has the option to await.
Here's a brief description about async/await methods.
Async Methods:
Caller is not necessarily blocked for the full execution of async
method
Possible return types
void: “fire-and-forget”
Task: allows to await termination of async method
Task<T>: allows to await termination and get result of type T
No ref or out parameter for async methods
Must again contain an await => Otherwise compile warning
await for Tasks
Await termination of a TPL task
Return result of task (if task with
result type)
Must only occur in async methods => Otherwise compile error
An async method is partly synchronous and partly asynchronous
Caller synchronously executes the method until a blocking await
Thereafter, the method rest is asynchronously executed
async & await Mechanism
Efficient
public async Task<int> GetSiteLengthAsync(string url)
{
HttpClient client = new HttpClient(); <= Sync
Task<string> download1 = client.GetStringAsync(url); <= Sync
string site1 = await download1; <= Async (Another thread)
return site1.Length; <= Async (Another thread)
}
Not sure if that simplier for you to understand that in the following way, but this is how it helped myself:
As you can see, the AccessTheWebAsync returns Task<int> but not just int.
If you would have called it without "await", you would just get the Task<int> object as its result. And could do anything further you want (manually) with that task: for instance, to wait until it finishes theTask.Wait(); and obtain the result of int in theTask.Result.
But await does all that instead of you and returns just int: Task<int> => int.
This is it.
from MSDN:
the await operator is applied to a task in an asynchronous method to suspend the execution of the method until the awaited task completes. The task represents ongoing work.await does not block the thread on which it is executing. Instead, it causes the compiler to sign up the rest of the async method as a continuation on the awaited task. Control then returns to the caller of the async method. When the task completes, it invokes its continuation, and execution of the async method resumes where it left off.
So when the compiler encounter
int contentLength = await AccessTheWebAsync();
it waits till the AccessTheWebAsync() task is complted
please take a look at this example C# Async,Await
All await does is blocks the thread until the result of an async operation returns.
Edit: sorry when I said block I should have said suspend, since blocking would prevent execution from continuing!
Edit2: As Alex pointed out - I should have probably said "execution is suspended" rather than the thread. Basically "Stuff happens until await returns but the point is it appears you are writing and executing synchronous code"
Since async operations have the potential to be take a while (e.g. web service calls), they tend to use callbacks to return a result.
If you have to handle callbacks in your code it can get a little messy, especially when waiting on multiple async tasks that are dependant on each other. Async/await and Task simplify the code so that you can write async code literally in the order you would read it.
e.g. example standard async code with callbacks:
public int CallSomeServiceAndReturnItsValue()
{
int result = 0;
WebService.SomeAsyncServiceCall((svcResult) => { result = svcResult.Value; });
return result;
}
and if you have multiple calls that need to be chained:
public int CallSomeServiceAndReturnItsValue()
{
int result = 0;
WebService.GetSomeIdentifier((svcResult) =>
{
var identifier = svcResult.Value;
WebService.GetResult(identifier, (anotherResult) =>
{
result = anotherResult.Value;
}
}
);
return result;
}
As you can see, it starts getting messy, the code doesn't really read in an order that feels natural. The alternative is to use callback methods instead of anonymous methods but still, the callback methods are far away from the code that called them and things can feel disjointed
The other alternative is of course async/await which is much clearer
public int CallSomeServiceAndReturnItsValue()
{
int identifier = await WebService.GetSomeIdentifier();
return await WebService.GetResult(identifier);
}

Wait for a void async method

How can I wait for a void async method to finish its job?
for example, I have a function like below:
async void LoadBlahBlah()
{
await blah();
...
}
now I want to make sure that everything has been loaded before continuing somewhere else.
Best practice is to mark function async void only if it is fire and forget method, if you want to await on, you should mark it as async Task.
In case if you still want to await, then wrap it like so await Task.Run(() => blah())
If you can change the signature of your function to async Task then you can use the code presented here
The best solution is to use async Task. You should avoid async void for several reasons, one of which is composability.
If the method cannot be made to return Task (e.g., it's an event handler), then you can use SemaphoreSlim to have the method signal when it is about to exit. Consider doing this in a finally block.
You don't really need to do anything manually, await keyword pauses the function execution until blah() returns.
private async void SomeFunction()
{
var x = await LoadBlahBlah(); <- Function is not paused
//rest of the code get's executed even if LoadBlahBlah() is still executing
}
private async Task<T> LoadBlahBlah()
{
await DoStuff(); <- function is paused
await DoMoreStuff();
}
T is type of object blah() returns
You can't really await a void function so LoadBlahBlah() cannot be void
I know this is an old question, but this is still a problem I keep walking into, and yet there is still no clear solution to do this correctly when using async/await in an async void signature method.
However, I noticed that .Wait() is working properly inside the void method.
and since async void and void have the same signature, you might need to do the following.
void LoadBlahBlah()
{
blah().Wait(); //this blocks
}
Confusingly enough async/await does not block on the next code.
async void LoadBlahBlah()
{
await blah(); //this does not block
}
When you decompile your code, my guess is that async void creates an internal Task (just like async Task), but since the signature does not support to return that internal Tasks
this means that internally the async void method will still be able to "await" internally async methods. but externally unable to know when the internal Task is complete.
So my conclusion is that async void is working as intended, and if you need feedback from the internal Task, then you need to use the async Task signature instead.
hopefully my rambling makes sense to anybody also looking for answers.
Edit:
I made some example code and decompiled it to see what is actually going on.
static async void Test()
{
await Task.Delay(5000);
}
static async Task TestAsync()
{
await Task.Delay(5000);
}
Turns into (edit: I know that the body code is not here but in the statemachines, but the statemachines was basically identical, so I didn't bother adding them)
private static void Test()
{
<Test>d__1 stateMachine = new <Test>d__1();
stateMachine.<>t__builder = AsyncVoidMethodBuilder.Create();
stateMachine.<>1__state = -1;
AsyncVoidMethodBuilder <>t__builder = stateMachine.<>t__builder;
<>t__builder.Start(ref stateMachine);
}
private static Task TestAsync()
{
<TestAsync>d__2 stateMachine = new <TestAsync>d__2();
stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
stateMachine.<>1__state = -1;
AsyncTaskMethodBuilder <>t__builder = stateMachine.<>t__builder;
<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
neither AsyncVoidMethodBuilder or AsyncTaskMethodBuilder actually have any code in the Start method that would hint of them to block, and would always run asynchronously after they are started.
meaning without the returning Task, there would be no way to check if it is complete.
as expected, it only starts the Task running async, and then it continues in the code.
and the async Task, first it starts the Task, and then it returns it.
so I guess my answer would be to never use async void, if you need to know when the task is done, that is what async Task is for.
do a AutoResetEvent, call the function then wait on AutoResetEvent and then set it inside async void when you know it is done.
You can also wait on a Task that returns from your void async
You can simply change the return type to Task and call await Task.CompletedTask at the end of the function, e.g:
async Task MyFunction() {
await AnotherFunction();
await Task.CompletedTask;
}
I find this simpler than wrapping the whole function body in a call to Task.Run(() => { ... });.
I've read all the solutions of the thread and it's really complicated... The easiest solution is to return something like a bool:
async bool LoadBlahBlah()
{
await blah();
return true;
}
It's not mandatory to store or chekc the return value. You can juste do:
await LoadBlahBlah();
... and you can return false if something goes wrong.

Categories