In constructor I want to call one method type :
private async Task OnLoadPrometDanKorisnikDatum
and I want to wait that method while its finish, and I have more method(3) like this and I want to call this 3 methods in background thread and don't wait him to finish, just want to wait first method. And I want to them executing parallel.
I have methods async Task,and in constructor of view model I call like this
OnLoadPrometDanKorisnikDatum(KorisnikID, PomocnaDnDDatnaDat,
DatumVrednost).Wait();
OnLoadPrometNedelja(KorisnikID, PomocnaDnDDatnaDatNedelja).Wait();
if I don't place .Wait() on the end, program doesn't work. I see in debug mode they run asynchronly, but time spent tell me that they sub(one method time + second method time + ....).
Can someone help me, this is for me very stuf...
Answer
The best way to handle your scenario is to use async void.
I recommend first reading the Explanation section below to fully understand the best practices around async void.
public MyConstructor()
{
ExecuteAsyncMethods();
}
async void ExecuteAsyncMethods()
{
try
{
await OnLoadPrometDanKorisnikDatum(KorisnikID, PomocnaDnDDatnaDat, DatumVrednost);
await OnLoadPrometNedelja(KorisnikID, PomocnaDnDDatnaDatNedelja);
}
catch(Exception e)
{
//Handle Exception
}
}
Explanation
Many C# devs are taught "Never use async void", but this is one of the few use-cases for it.
Yes async void can be dangerous and here's why:
Cannot await an async avoid method
Can lead to race conditions
Difficult to catch an Exception thrown by async void methods
E.g. the following try/catch block will not catch the Exception thrown here:
public MyConstructor()
{
try
{
//Cannot await `async void`
AsyncVoidMethodWithException();
}
catch(Exception e)
{
//Will never catch the `Exception` thrown in `AsyncVoidMethodWithException` because `AsyncVoidMethodWithException` cannot be awaited
}
//code here will be executing by the time `AsyncVoidMethodWithException` throws the exception
}
async void AsyncVoidMethodWithException()
{
await Task.Delay(2000);
throw new Exception();
}
That being said, as long as we wrap the contents of our entire async void in a try/catch block, we will be able to catch the exception, like so:
public MyConstructor()
{
AsyncVoidMethodWithException();
}
async void AsyncVoidMethodWithException()
{
try
{
await Task.Delay(2000);
throw new Exception();
}
catch(Exception e)
{
//Exception will be caught and successfully handled
}
}
SafeFireAndForget
I created a library to help with this and its additional benefit is that it avoids writing async void code that could be potentially misused by future devs.
It's open source and also available on NuGet:
Source Code
NuGet Package
SafeFireAndForget
SafeFireAndForget allows us to safely execute a Task whilst not blocking the calling thread and without waiting for it to finish before moving to the next line of code.
Below is a simplified version of SafeFireAndForget that you can add to your project.
However, I recommend copy/pasting its complete source code or adding its NuGet Package to your library to get a more robust implementation
public static async void SafeFireAndForget<TException>(this Task task, Action<TException> onException = null, bool continueOnCapturedContext = false) where TException : Exception
{
try
{
await task.ConfigureAwait(continueOnCapturedContext);
}
catch (TException ex) when (onException != null)
{
onException(ex);
}
}
Using SafeFireAndForget
To use SafeFireAndForget, append it to your method call like so:
OnLoadPrometDanKorisnikDatum(KorisnikID, PomocnaDnDDatnaDat, DatumVrednost).SafeFireAndForget();
OnLoadPrometNedelja(KorisnikID, PomocnaDnDDatnaDatNedelja).SafeFireAndForget();
To handle any Exception thrown by that Task, use onException. Here's an example that prints the Exception to the Debug Console:
OnLoadPrometDanKorisnikDatum(KorisnikID, PomocnaDnDDatnaDat, DatumVrednost).SafeFireAndForget(ex => Debug.WriteLine(ex));
OnLoadPrometNedelja(KorisnikID, PomocnaDnDDatnaDatNedelja).SafeFireAndForget(ex => Debug.WriteLine(ex));
I have an async codeblock running on the pageload.
The codes run smoothy until you reach capturevalue method where we create a new task.On executing that code block the await just freezes and then the control doesnt come back seems like the code just went to deadlock
protected void Page_Load(object sender, EventArgs e)
{
try
{
var textvalue = GetTextValueFromTask();
txtbox.Text = textvalue.Result;
string ss = "";
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
private async Task<string> GetTextValueFromTask()
{
string strReturn = await CaptureValue();
return strReturn;
}
private async Task<string> CaptureValue()
{
Thread.Sleep(5000);
Task<string> T = Task.Factory.StartNew<string>(() => "hi");
return await T;
}
Then I made a small change in Capturevalue method.
private async Task<string> CaptureValue()
{
Thread.Sleep(5000);
Task<string> T = Task.Factory.StartNew<string>(() => "hi");
string ss = T.Result;
return await T;
}
Once I made that change it started working normal.What difference did it make on just fetching the result initially. Please help me Iam a newbee to async
The difference is that second time it doesn't happen any "await" because you waited the task yourself, so await doesn't do anything.
I think you missed the await keyword the first time, here:
var textvalue = await GetTextValueFromTask();
Without it your method GetTextValueFromTask runs synchronously, then it comes into CaptureValue method where await occurs. But the default behaviour of the await is that it tries to capture synchronization context where it was called and to continue the rest of the method in that context, in your example it is WPF synchronization context, which does not allow more than one thread to execute at once. But the continuation cannot proceed, because context is already used by await mechanism.
So, one more time. There is one thread (UI thread), that executes your code up to the last await, which is return await T;, then it yields back to the caller - GetTextValueFromTask, and again to the Page_Load when it gets blocked, because initially you called GetTextValueFromTask synchronously (without await). After that, your operation T completes, and your code tries to continue executing using the initial synchronization context, the WPF one. But it can't, because it is already waiting in the Page_Load.
The link in the comments describes the situation in more detail.
Also consider not using Thread.Sleep in async/await scenarios, because it kills all the "asynchronous" nature of the code. Further reading: link.
Another general piece of advice, which is not directly applicable to your source code, is not to use Task.Factory.StartNew, but rather use Task.Run. Explanation here.
Please use Task.Run() instead of Task.Factory.StartNew()
var T = Task.Run(() => "hi");
It's up to Task.Run to decide how to handle this task.
Also please use .ConfigureAwait(false) in your await calls that do not requires the continuation being done in the awaiter thread context.
Is it appropriate to use async void method to start some long-living operation? I know Nito or Task.Run() could be used to Run Task from non-async method. What is the difference? Are there any pitfalls?
By all that I mean, can I write like that:
async void bar()
{
try
{
//...
}
catch (Exception ex)
{
// no rethrowing here
}
}
void foo()
{
bar();
// will continue right after 1st await in bar()
baz();
}
In any case it would be better to use async Task to get better error handling behavior. You don't need to await the resulting task.
In your code snippet the comment will continue right after 1st await in bar is not necessarily correct. As it stands bar will synchronously execute and block foo because bar has no awaits in it.
Starting a long running operation requires to either use async IO or to use a new thread/task in some way (Task.Run is appropriate).
I am developing android messanger app based on xamarin and .net 5 async/awaits.
In my app i have producer/consumer pattern for processing messages which is made on infinite loops.
for example ReadTcpClientAsync producer:
async Task ReadTcpClientAsync(CancellationToken cancellationToken)
{
cde.Signal();
while (!cancellationToken.IsCancellationRequested)
{
byte[] buffer = await atc.ReadAsync(cancellationToken);
// queue message...
}
}
or SendStatementsAsync consumer which deque messages and awaits WriteAsync
private async Task SendStatementsAsync(CancellationToken cancellationToken)
{
while (!cancellationToken.IsCancellationRequested)
{
var nextItem = await _outputStatements.Take();
cancellationToken.ThrowIfCancellationRequested();
// misc ...
await atc.WriteAsync(call.Serialize());
}
}
and some consumers just await on Take calls
var update = await _inputUpdateStatements.Take();
this construction works pretty well on tests, but there is one method where i think i made a huge mistake.
this method intent to run entire client backend, starting 3 pro/con while (true) loops simultaneously.
here it is:
public async Task RunAsync()
{
_isRunning = true;
_progress.ProgressChanged += progress_ProgressChanged;
await InitMTProto(_scheme).ConfigureAwait(false); // init smth...
// various init stuf...
await atc.ConnectAsync().ConfigureAwait(false); // open connection async
// IS IT WRONG?
try
{
await Task.WhenAny(SendStatementsAsync(_cts.Token),
ReadTcpClientAsync(_cts.Token),
ProcessUpdateAsync(_cts.Token, _progress)).ConfigureAwait(false);
}
catch (OperationCanceledException oce)
{
}
catch (Exception ex)
{
}
}
Forget about android for now, think any UI (WinForm, WPF, etc) OnCreate method in UI context to call RunAsync
protected async override void OnCreate(Bundle bundle)
{
// start RA
await client.RunAsync()
// never gets here - BAD, but nonblock UI thread - good
Debug.WriteLine("nevar");
}
so, as you can see there is a problem. I can't do anything after RunAsync await call because it will never returns from Task.WhenAny(...). And i need perform status check there, but i need this pro/cons methods started, because my check wait on ManualResetEvent for it:
if (!cde.Wait(15000))
{
throw new TimeoutException("Init too long");
}
Also, my check is async too, and it works like a charm :)
public async Task<TLCombinatorInstance> PerformRpcCall(string combinatorName, params object[] pars)
{
// wait for init on cde ...
// prepare call ...
// Produce
ProduceOutput(call);
// wait for answer
return await _inputRpcAnswersStatements.Take();
}
I think i should use another approach for starting this infinite loops, but i already have async Task methods all the way - so i really have no idea what to do.
Any help please?
Ok, after a lot of reading (nothing found) and #svick's advice i decided to call this methods without "await" as separate Task.Run's.
Aso i decided to run it in ThreadPool.
My final code is:
try
{
/*await Task.WhenAny(SendStatementsAsync(_cts.Token),
ReadTcpClientAsync(_cts.Token),
ProcessUpdateAsync(_cts.Token, _progress)).ConfigureAwait(false);*/
Task.Run(() => SendStatementsAsync(_cts.Token)).ConfigureAwait(false);
Task.Run(() => ReadTcpClientAsync(_cts.Token)).ConfigureAwait(false);
Task.Run(() => ProcessUpdateAsync(_cts.Token, _progress)).ConfigureAwait(false);
Trace.WriteLineIf(clientSwitch.TraceInfo, "Worker threads started", "[Client.RunAsync]");
}
Everything works fine as expected..
i'm not sure what problems it will cause in exception handling, as i know they will be lost
Of course such calls produce warning
Because this call is not awaited, execution of the current method
continues before the call is completed. Consider applying the 'await'
operator to the result of the call.
which can be easily suppressed this way
// just save task into variable
var send = Task.Run(() => SendStatementsAsync(_cts.Token)).ConfigureAwait(false);
Also, if anyone know better solution i will be grateful to hear it.
I have an async method which returns no data:
public async Task MyAsyncMethod()
{
// do some stuff async, don't return any data
}
I'm calling this from another method which returns some data:
public string GetStringData()
{
MyAsyncMethod(); // this generates a warning and swallows exceptions
return "hello world";
}
Calling MyAsyncMethod() without awaiting it causes a "Because this call is not awaited, the current method continues to run before the call is completed" warning in visual studio. On the page for that warning it states:
You should consider suppressing the warning only if you're sure that you don't want to wait for the asynchronous call to complete and that the called method won't raise any exceptions.
I'm sure I don't want to wait for the call to complete; I don't need to or have the time to. But the call might raise exceptions.
I've stumbled into this problem a few times and I'm sure it's a common problem which must have a common solution.
How do I safely call an async method without awaiting the result?
Update:
For people suggesting that I just await the result, this is code that is responding to a web request on our web service (ASP.NET Web API). Awaiting in a UI context keeps the UI thread free, but awaiting in a web request call will wait for the Task to finish before responding to the request, thereby increasing response times with no reason.
If you want to get the exception "asynchronously", you could do:
MyAsyncMethod().
ContinueWith(t => Console.WriteLine(t.Exception),
TaskContinuationOptions.OnlyOnFaulted);
This will allow you to deal with an exception on a thread other than the "main" thread. This means you don't have to "wait" for the call to MyAsyncMethod() from the thread that calls MyAsyncMethod; but, still allows you to do something with an exception--but only if an exception occurs.
Update:
technically, you could do something similar with await:
try
{
await MyAsyncMethod().ConfigureAwait(false);
}
catch (Exception ex)
{
Trace.WriteLine(ex);
}
...which would be useful if you needed to specifically use try/catch (or using) but I find the ContinueWith to be a little more explicit because you have to know what ConfigureAwait(false) means.
You should first consider making GetStringData an async method and have it await the task returned from MyAsyncMethod.
If you're absolutely sure that you don't need to handle exceptions from MyAsyncMethod or know when it completes, then you can do this:
public string GetStringData()
{
var _ = MyAsyncMethod();
return "hello world";
}
BTW, this is not a "common problem". It's very rare to want to execute some code and not care whether it completes and not care whether it completes successfully.
Update:
Since you're on ASP.NET and wanting to return early, you may find my blog post on the subject useful. However, ASP.NET was not designed for this, and there's no guarantee that your code will run after the response is returned. ASP.NET will do its best to let it run, but it can't guarantee it.
So, this is a fine solution for something simple like tossing an event into a log where it doesn't really matter if you lose a few here and there. It's not a good solution for any kind of business-critical operations. In those situations, you must adopt a more complex architecture, with a persistent way to save the operations (e.g., Azure Queues, MSMQ) and a separate background process (e.g., Azure Worker Role, Win32 Service) to process them.
The answer by Peter Ritchie was what I wanted, and Stephen Cleary's article about returning early in ASP.NET was very helpful.
As a more general problem however (not specific to an ASP.NET context) the following Console application demonstrates the usage and behavior of Peter's answer using Task.ContinueWith(...)
static void Main(string[] args)
{
try
{
// output "hello world" as method returns early
Console.WriteLine(GetStringData());
}
catch
{
// Exception is NOT caught here
}
Console.ReadLine();
}
public static string GetStringData()
{
MyAsyncMethod().ContinueWith(OnMyAsyncMethodFailed, TaskContinuationOptions.OnlyOnFaulted);
return "hello world";
}
public static async Task MyAsyncMethod()
{
await Task.Run(() => { throw new Exception("thrown on background thread"); });
}
public static void OnMyAsyncMethodFailed(Task task)
{
Exception ex = task.Exception;
// Deal with exceptions here however you want
}
GetStringData() returns early without awaiting MyAsyncMethod() and exceptions thrown in MyAsyncMethod() are dealt with in OnMyAsyncMethodFailed(Task task) and not in the try/catch around GetStringData()
I end up with this solution :
public async Task MyAsyncMethod()
{
// do some stuff async, don't return any data
}
public string GetStringData()
{
// Run async, no warning, exception are catched
RunAsync(MyAsyncMethod());
return "hello world";
}
private void RunAsync(Task task)
{
task.ContinueWith(t =>
{
ILog log = ServiceLocator.Current.GetInstance<ILog>();
log.Error("Unexpected Error", t.Exception);
}, TaskContinuationOptions.OnlyOnFaulted);
}
This is called fire and forget, and there is an extension for that.
Consumes a task and doesn't do anything with it. Useful for fire-and-forget calls to async methods within async methods.
Install nuget package.
Use:
MyAsyncMethod().Forget();
EDIT: There is another way I've been rather using lately:
_ = MyAsyncMethod();
Not the best practice, you should try avoiding this.
However, just to address "Call an async method in C# without await", you can execute the async method inside a Task.Run. This approach will wait until MyAsyncMethod finish.
public string GetStringData()
{
Task.Run(()=> MyAsyncMethod()).Result;
return "hello world";
}
await asynchronously unwraps the Result of your task, whereas just using Result would block until the task had completed.
If you want to wrap it in a helper class:
public static class AsyncHelper
{
public static void Sync(Func<Task> func) => Task.Run(func).ConfigureAwait(false);
public static T Sync<T>(Func<Task<T>> func) => Task.Run(func).Result;
}
and call like
public string GetStringData()
{
AsyncHelper.Sync(() => MyAsyncMethod());
return "hello world";
}
I'm late to the party here, but there's an awesome library I've been using which I haven't seen referenced in the other answers
https://github.com/brminnick/AsyncAwaitBestPractices
If you need to "Fire And Forget" you call the extension method on the task.
Passing the action onException to the call ensures that you get the best of both worlds - no need to await execution and slow your users down, whilst retaining the ability to handle the exception in a graceful manner.
In your example you would use it like this:
public string GetStringData()
{
MyAsyncMethod().SafeFireAndForget(onException: (exception) =>
{
//DO STUFF WITH THE EXCEPTION
});
return "hello world";
}
It also gives awaitable AsyncCommands implementing ICommand out the box which is great for my MVVM Xamarin solution
Typically async method returns Task class. If you use Wait() method or Result property and code throws exception - exception type gets wrapped up into AggregateException - then you need to query Exception.InnerException to locate correct exception.
But it's also possible to use .GetAwaiter().GetResult() instead -
it will also wait async task, but will not wrap exception.
So here is short example:
public async Task MyMethodAsync()
{
}
public string GetStringData()
{
MyMethodAsync().GetAwaiter().GetResult();
return "test";
}
You might want also to be able to return some parameter from async function - that can be achieved by providing extra Action<return type> into async function, for example like this:
public string GetStringData()
{
return MyMethodWithReturnParameterAsync().GetAwaiter().GetResult();
}
public async Task<String> MyMethodWithReturnParameterAsync()
{
return "test";
}
Please note that async methods typically have ASync suffix naming, just to be able to avoid collision between sync functions with same name. (E.g. FileStream.ReadAsync) - I have updated function names to follow this recommendation.
I guess the question arises, why would you need to do this? The reason for async in C# 5.0 is so you can await a result. This method is not actually asynchronous, but simply called at a time so as not to interfere too much with the current thread.
Perhaps it may be better to start a thread and leave it to finish on its own.
On technologies with message loops (not sure if ASP is one of them), you can block the loop and process messages until the task is over, and use ContinueWith to unblock the code:
public void WaitForTask(Task task)
{
DispatcherFrame frame = new DispatcherFrame();
task.ContinueWith(t => frame.Continue = false));
Dispatcher.PushFrame(frame);
}
This approach is similar to blocking on ShowDialog and still keeping the UI responsive.
Maybe I'm too naive but, couldn't you create an event that is raised when GetStringData() is called and attach an EventHandler that calls and awaits the async method?
Something like:
public event EventHandler FireAsync;
public string GetStringData()
{
FireAsync?.Invoke(this, EventArgs.Empty);
return "hello world";
}
public async void HandleFireAsync(object sender, EventArgs e)
{
await MyAsyncMethod();
}
And somewhere in the code attach and detach from the event:
FireAsync += HandleFireAsync;
(...)
FireAsync -= HandleFireAsync;
Not sure if this might be anti-pattern somehow (if it is please let me know), but it catches the Exceptions and returns quickly from GetStringData().
The solution is start the HttpClient into another execution task without sincronization context:
var submit = httpClient.PostAsync(uri, new StringContent(body, Encoding.UTF8,"application/json"));
var t = Task.Run(() => submit.ConfigureAwait(false));
await t.ConfigureAwait(false);
It is straightforward, just call asyncMethod().Result to call without await. Below is the sample code and here is the fiddle
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
var asyncDemo = new AsyncDemo();
asyncDemo.TestMethod1Void().Wait();
var result = asyncDemo.TestMethod1().Result;
Console.WriteLine(result);
}
}
public class AsyncDemo {
public async Task<string> TestMethod1()
{
Thread.Sleep(1000);
return "From Async Method";
}
public async Task TestMethod1Void()
{
Thread.Sleep(1000);
Console.WriteLine("Async Void Method");
}
}