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?
If you use a Task return type for an async method, a calling method can use an await operator to suspend the caller's completion until the called async method has finished. In the following example, the WaitAndApologizeAsync method doesn't contain a return statement, so the method returns a Task object.
Async functions always return a promise. If the return value of an async function is not explicitly a promise, it will be implicitly wrapped in a promise. Note: Even though the return value of an async function behaves as if it's wrapped in a Promise.resolve , they are not equivalent.
Long story short, in order to return response in Async function, you either need a callback or use async/await structure. From the above code, you can understand the flow of asynchronous functions.
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 = Task.Run(async () => await UploadInvoiceAsync("assessment1", "filename")); task.Wait(); string invoiceIdAsync = task.Result; }
----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)); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With