'How to return a result from an async task?
I would like to return a string result from an async task.
System.Threading.Tasks.Task.Run(async () => await audatex.UploadInvoice(assessment, fileName));
public async Task UploadInvoice(string assessment, string fileName)
{
//Do stuff
return string;
}
Async programming confuses me, can someone please explain it?
Solution 1:[1]
Your method should return Task<string>
, not Task
:
public async Task<string> UploadInvoice(string assessment, string fileName)
{
//Do stuff
return string;
}
Solution 2:[2]
Async programming can take a while to get your head around, so I'll post what has been useful for me in case it helps anyone else.
If you want to separate the business logic from the async code, you can keep your UploadInvoice method async-free:
private string UploadInvoice(string assessment, string filename)
{
// Do stuff
Thread.Sleep(5000);
return "55";
}
Then you can create an async wrapper:
private async Task<string> UploadInvoiceAsync(string assessment, string filename)
{
return await Task.Run(() => UploadInvoice(assessment, filename));
}
Giving you the choice of which to call:
public async Task CallFromAsync()
{
string blockingInvoiceId = UploadInvoice("assessment1", "filename");
string asyncInvoiceId = await UploadInvoiceAsync("assessment1", "filename");
}
Sometimes you might need to call an async method from a non-async method.
// Call the async method from a non-async method
public void CallFromNonAsync()
{
string blockingInvoiceId = UploadInvoice("assessment1", "filename");
Task<string> task = UploadInvoiceAsync("assessment1", "filename");
string invoiceIdAsync = task.GetAwaiter().GetResult();
}
----EDIT: Adding more examples because people have found this useful----
Sometimes you want to wait on a task, or continue a task with a method on completion. Here's a working example you can run in a console application.
class Program
{
static void Main(string[] args)
{
var program = new Program();
program.Run();
Console.ReadKey();
}
async void Run()
{
// Example 1
Console.WriteLine("#1: Upload invoice synchronously");
var receipt = UploadInvoice("1");
Console.WriteLine("Upload #1 Completed!");
Console.WriteLine();
// Example 2
Console.WriteLine("#2: Upload invoice asynchronously, do stuff while you wait");
var upload = UploadInvoiceAsync("2");
while (!upload.IsCompleted)
{
// Do stuff while you wait
Console.WriteLine("...waiting");
Thread.Sleep(900);
}
Console.WriteLine("Upload #2 Completed!");
Console.WriteLine();
// Example 3
Console.WriteLine("#3: Wait on async upload");
await UploadInvoiceAsync("3");
Console.WriteLine("Upload #3 Completed!");
Console.WriteLine();
// Example 4
var upload4 = UploadInvoiceAsync("4").ContinueWith<string>(AfterUploadInvoice);
}
string AfterUploadInvoice(Task<string> input)
{
Console.WriteLine(string.Format("Invoice receipt {0} handled.", input.Result));
return input.Result;
}
string UploadInvoice(string id)
{
Console.WriteLine(string.Format("Uploading invoice {0}...", id));
Thread.Sleep(2000);
Console.WriteLine(string.Format("Invoice {0} Uploaded!", id));
return string.Format("<{0}:RECEIPT>", id); ;
}
Task<string> UploadInvoiceAsync(string id)
{
return Task.Run(() => UploadInvoice(id));
}
}
Solution 3:[3]
public async Task<string> UploadInvoice(string assessment, string fileName)
{
string result = GetResultString();//Do stuff
return Task.FromResult(result);
}
Solution 4:[4]
Do this:
public async Task<string> UploadInvoice(string assessment, string fileName)
Then await
the result:
string result = await UploadInvoice("", "");
More examples can be seen here:
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | w.b |
Solution 2 | |
Solution 3 | Jayesh Dhananjayan |
Solution 4 | Ric |