I'm trying to learn and implement async / await keywords on my application. I'm using an API to get data then showing them on my forms. When I try to call methods from an console application there is no problem. But if I call my async methods from Form_Shown event also there no exception but methods not working.
So I'm calling my RefreshOrLoadDataToCache() method on Form_Shown event.
private async void LogTimeReport_Shown(object sender, EventArgs e)
{
// Some syncronous operations
RefreshOrLoadDataToCache(); // Async methods in it
// Some syncronous operations
}
In my this method created a task and wait for it.
private async void RefreshOrLoadDataToCache()
{
if (IsNeededToCallAPI())
{
var taskForTimeEntries = LoadTimeEntriesTemp();
Task.WhenAll(taskForTimeEntries);
DataTable dtTimeEntriesTemp = taskForTimeEntries.Result;
DataTable dtEventsTemp = LoadEventsTemp();
dtTimeEntriesTemp.Merge(dtEventsTemp);
}
else
BindGridViews();
}
This my async method.
private async Task<DataTable> LoadTimeEntriesTemp()
{
TimeEntryHandler timeHandler = new TimeEntryHandler();
TimeEntryResponse response = await timeHandler.GetTimeEntries();
DataTable dt = DatatableHelper.ToDataTable<TimeEntry>(response.TimeEntries);
foreach (DataRow drow in dt.Rows)
{
// Some operations on DataTable
}
return dt;
}
In this method I'm connecting to API and getting results. I think my problem is about this method. Because when I call this method from console application it returns data. But from form application it waits for a long time but there is no result or exception.
private async Task<TimeEntryResponse> GetTimeEntries()
{
using (var client = new AuthorizedHttpClient(_client))
{
var data = await client.GetAsync<TimeEntryResponse>(parameters);
if (data.StatusCode == HttpStatusCode.OK)
{
var response = (TimeEntryResponse)data.ContentObj;
response.Pages = int.Parse(data.Headers.GetValues("X-Pages").First());
response.Page = int.Parse(data.Headers.GetValues("X-Page").First());
response.TotalRecords = int.Parse(data.Headers.GetValues("X-Records").First());
return response;
}
return new TimeEntryResponse() { TimeEntries = null, STATUS = "ERROR" };
}
}
I thought that there is something I'm missing about asyncronous calls on windows forms. How can I fix my code ?
You have a couple of problems with your code
You mark a method as async, but you don't await on the operation inside. You currently do this because RefreshOrLoad is async void. It actually needs to be async Task, where the underlying returned task is the ongoing async operation. Then, the returned Task should be awaited on:
private async void LogTimeReport_Shown(object sender, EventArgs e)
{
// Some syncronous operations
await RefreshOrLoadDataToCache(); // Async methods in it
// Some syncronous operations
}
RefreshOrLoad is an async method. You use Task.WhenAll, which is used for asynchronously waiting on multiple tasks, but you don't await on it either. Then, you call .Result, which causes your code to effectively deadlock. All that's needed is to await the task returning from LoadTimeEntriesTemp:
private async Task RefreshOrLoadDataToCache()
{
if (IsNeededToCallAPI())
{
DataTable dtTimeEntriesTemp = await LoadTimeEntriesTemp();
DataTable dtEventsTemp = LoadEventsTemp();
dtTimeEntriesTemp.Merge(dtEventsTemp);
}
else
BindGridViews();
}
I'd also note that you should use the *Async postfix with your async methods.
When fixing these, you'll see that your code behaves as expected, being asynchronous all the way down.
You problem here:
var taskForTimeEntries = LoadTimeEntriesTemp();
Task.WhenAll(taskForTimeEntries);
DataTable dtTimeEntriesTemp = taskForTimeEntries.Result;
At first, why do you use Task.WhenAll when you have just one task? That way you leak the task returned by Task.WhenAll which will be completed and indicate that all your tasks that are passed to Task.WhenAll are completed. It will wait for the task synchronously which will cause deadlock.
There is a rule for async/await which states await in all ways
So right approach is:
DataTable dtTimeEntriesTemp = await LoadTimeEntriesTemp();
Also, you should await on RefreshOrLoadDataToCache(); in your event handler if you want to do synchronous operations related to its result.
Here is a great article by Stephen Cleary Don't Block on Async Code which describes your problem in more details.
Method RefreshOrLoadDataToCache() is marked as async yet it does not use await on Task.WhenAll() and LogTimeReport_Shown() does not have to be async. :
private async void RefreshOrLoadDataToCache()
{
if (IsNeededToCallAPI())
{
var taskForTimeEntries = LoadTimeEntriesTemp();
DataTable dtTimeEntriesTemp = await taskForTimeEntries; // call await here
DataTable dtEventsTemp = LoadEventsTemp();
dtTimeEntriesTemp.Merge(dtEventsTemp);
}
else
BindGridViews();
}
Related
My async method is as below:
public async Task<List<object>> handleSummaryOfWallets()
{
string token = giveMeToken("URL AND CREDS");
Channel channel = new Channel("NANANANA GIROUD", ChannelCredentials.Insecure);
OMGadminAPI.OMGadminAPIClient client = new OMGadminAPI.OMGadminAPIClient(channel);
var summaryBalancesParams = new OMGadminAPIGetCurrenciesSummariesParams();
summaryBalancesParams.AdminAuthTokenSecret = token;
List<object> summariesCurrenciesOMGadmin = new List<object>();
using (var call = client.GetCurrenciesSummaries(summaryBalancesParams))
{
while (await call.ResponseStream.MoveNext())
{
OMGadminAPICurrencySummary currencySummary = call.ResponseStream.Current;
summariesCurrenciesOMGadmin.Add(currencySummary);
Console.WriteLine(summariesCurrenciesOMGadmin);
}
return summariesCurrenciesOMGadmin;
}
}
As you can see, above async method returns list of objects. I call this method as below:
var listOfBalances = balances.handleSummaryOfWallets().Wait();
and it gives me error:
Error CS0815: Cannot assign void to an implicitly-typed variable
From the error, I understand that this is not correct way to call async method. But I need to read ready list of objects from async fetched data. Its request-response, no real stable stream. So I need to generate this list only once per request. I'm using gRPC framework for RPC calls.
Please help me fetch this data and make ready to use.
The Task.Wait method waits for the Task to complete execution. It returns void. That is the reason why the exception.
Now to overcome the exception and to read the return value, one way is as mentioned in other answer and the comments; await the call as below:
public async void TestAsync()
{
var listOfBalances = await handleSummaryOfWallets();
}
Note that your calling method should also be async method now.
As you are calling Wait in your code, it looks that you want the result immediately; you have nothing else left to do that does not depend on result. In that case, you may choose to stop async chain by calling Wait. But you need to do some changes as below:
public void TestAsync()
{
var task = handleSummaryOfWallets();//Just call the method which will return the Task<List<object>>.
task.Wait();//Call Wait on the task. This will hold the execution until complete execution is done.
var listOfBalances = task.Result;//Task is executed completely. Read the result.
}
Note that calling method is no longer async. Other explanation is given in code-comments.
Other short alternative to above code is as below:
public void TestAsync()
{
var listOfBalances = handleSummaryOfWallets().Result;
}
Just use await while calling your method
var listOfBalances = await balances.handleSummaryOfWallets();
I have a method which returns a task, which I want to call multiple times and wait for any 1 of them to be successful. The issue I am facing is as soon as I add the task to the List, it executes and since I added delay to simulate the work, it just block there.
Is there a way to add the the tasks to the list without really executing it and let whenAny execute the tasks.
The below code is from Linqpad editor.
async void Main()
{
var t = new Test();
List<Task<int>> tasks = new List<Task<int>>();
for( int i =0; i < 5; i++)
{
tasks.Add(t.Getdata());
}
var result = await Task.WhenAny(tasks);
result.Dump();
}
public class Test
{
public Task<int> Getdata()
{
"In Getdata method".Dump();
Task.Delay(90000).Wait();
return Task.FromResult(10);
}
}
Update :: Below one makes it clear, I was under the impression that if GetData makes a call to network it will get blocked during the time it actually completes.
async void Main()
{
OverNetwork t = new OverNetwork();
List<Task<string>> websitesContentTask = new List<Task<string>>();
websitesContentTask.Add(t.GetData("http://www.linqpad.net"));
websitesContentTask.Add(t.GetData("http://csharpindepth.com"));
websitesContentTask.Add(t.GetData("http://www.albahari.com/nutshell/"));
Task<string> completedTask = await Task.WhenAny(websitesContentTask);
string output = await completedTask;
Console.WriteLine(output);
}
public class OverNetwork
{
private HttpClient client = new HttpClient();
public Task<string> GetData(string uri)
{
return client.GetStringAsync(uri);
}
}
since I added delay to simulate the work, it just block there
Actually, your problem is that your code is calling Wait, which blocks the current thread until the delay is completed.
To properly use Task.Delay, you should use await:
public async Task<int> Getdata()
{
"In Getdata method".Dump();
await Task.Delay(90000);
return 10;
}
Is there a way to add the the tasks to the list without really executing it and let whenAny execute the tasks.
No. WhenAny never executes tasks. Ever.
It's possible to build a list of asynchronous delegates, i.e., a List<Func<Task>> and execute them later, but I don't think that's what you're really looking for.
There are multiple tasks in your Getdata method. First does delay, but you are returning finished task which returned 10. Try to change your code like this
return Task.Delay(90000).ContinueWith(t => 10)
As experiencing the new async & Await features of 4.5 I want to clear some confusions before going any further. I have been reading different article and also different question on SO and it help me undertands how Async and Await works. I will just try to put my understanding and confusions here and will appreciate if someone code educate me and other people who are looking for same things. I am discussing this in very simple wordings.
So Async is used so that compiler know that method marked by Async contains Await operation (Long operation). Latest framework contains different new builtin methods for Async Operations.
The builtin Async functions like connection.OpenAsync, ExecuteScalarAsync etc are used with Await keyword. I don't know the inner working of these Async Methods but my strong guess is that under the hood they are using Tasks.
Can I make this as general rule that Await will be with any method which implements Task. So if I need to create my own method which is performing long operation then will I create it as Task and when it is called I will use Await Keyword with it?
Second most important thing is that what is the rule of thumb of creating a method as Async or creating it as task. For example,
public void SampleMain()
{
for (int i = 1; i <= 100; i++)
{
DataTable dt = ReadData(int id);
}
}
public DataTable ReadData(int id)
{
DataTable resultDT = new DataTable();
DataTable dt1 = new DataTable();
// Do Operation to Fill DataTable from first connection string
adapter.Fill(dt1);
DataTable dt2 = new DataTable();
// Do Operation to Fill DataTable from first connection string
adapter.Fill(dt2);
// Code for combining datatable and returning the resulting datatable
// Combine DataTables
return resultDT;
}
public string GetPrimaryConnectionString()
{
// Retrieve connection string from some file io operations
return "some primary connection string";
}
public string GetSecondaryConnectionString()
{
// Retrieve connection string from some file io operations
return "some secondaryconnection string";
}
Now this is a very simple scenario that I have created based on some real world application I worked in past. So I was just wondering how to make this whole process Async.
Should I make GetPrimaryConnectionString and GetSecondaryConnectionString as Tasks and Await them in ReadData. Will ReadData be also a Task? How to call ReadData in the SampleMain function?
Another way could be to create a Task for ReadData in SampleMain and run that Task and skip converting other methods as Task. Is this the good approach? Will it be truly Asynchronous?
So Async is used so that compiler know that method marked by Async
contains Await operation
The async is used so that the compiler will have an indication to create a state-machine out of the method. An async method can have no await, and still work, though it will execute completely synchronously.
The builtin Async functions like connection.OpenAsync,
ExecuteScalarAsync etc are used with Await keyword. I don't know the
inner working of these Async Methods but my strong guess is that under
the hood they are using Tasks.
Task is a promise of work to be completed in the future. There are a couple of ways to create a Task. But, Task isn't the only thing that can be represent an asynchronous operation. You can create an awaitable yourself if you wanted, all it needs it to implement a GetAwaiter method which returns a type implementing INotifyCompletion.
If you want to know how a method is implemented in the framework, you can view the source. In this particular case, they use TaskCompletionSource<T>.
Should I make GetPrimaryConnectionString and
GetSecondaryConnectionString as Tasks and Await them in ReadData. Will
ReadData be also a Task? How to call ReadData in the SampleMain
function?
There is nothing inherently asynchronous about retrieving a connection string. You usually (not always) use async-await with naturally async IO operations. In this particular case, the only actual async operation is ReadData, and if you want to make it asynchronous, you can use SqlDataReader, which exposes async methods.
An example, taken from the ADO.NET teams blog:
public static async Task<Product> GetProductAndReviewsAsync(
int productID, int reviewsToGet)
{
using (SqlConnection connection = new SqlConnection(ConnectionString))
{
await connection.OpenAsync();
const string commandString = GetProductByIdCommand + ";"
+ GetProductReviewsPagedById;
using (SqlCommand command = new SqlCommand(commandString, connection))
{
command.Parameters.AddWithValue("productid", productID);
command.Parameters.AddWithValue("reviewStart", 0);
command.Parameters.AddWithValue("reviewCount", reviewsToGet);
using (SqlDataReader reader = await command.ExecuteReaderAsync())
{
if (await reader.ReadAsync())
{
Product product = GetProductFromReader(reader, productID);
if (await reader.NextResultAsync())
{
List<Review> allReviews = new List<Review>();
while (await reader.ReadAsync())
{
Review review = GetReviewFromReader(reader);
allReviews.Add(review);
}
product.Reviews = allReviews.AsReadOnly();
return product;
}
else
{
throw new InvalidOperationException(
"Query to server failed to return list of reviews");
}
}
else
{
return null;
}
}
}
}
}
how to make this whole process Async
If there are asynchronous versions of adapter.Fill, then simply await for it in ReadData, which in turn also become async and you can await for it in the caller method:
// in async button click event
button.Enabled = false;
var dt = await ReadData(int id);
button.Enabled = true;
... // do something with dt
public async Task<DataTable> ReadData(int id)
{
...
var job1 = adapter.AsyncFill(dt1);
var job2 = adapter.Fill(dt2);
// wait for all of them to finish
Task.WaitAll(new[] {job1, job2});
...
return Task.FromResult(resultDT); // dump approach
}
If there are no asynchronous version then you have to create them (by using Task):
// in async button click event
button.Enabled = false;
// run synchronous task asynchronously
var dt = await Task.Run(() => ReadData(int id));
button.Enabled = true;
... // do something with dt
async/await shines when it comes to UI, otherwise (if no UI is involved) just create task and run synchronous operation there.
The only reason to use async-await is if your main thread might do something useful while another thread is doing the length operation. If the main thread would start the other thread and only wait for the other thread to finish, it is better to let the main thread do the action.
One of the things a main thread quite often does is keep the UI responsive.
You are right, under the hood async-await uses Task, hence you see that an async function returns a Task.
The rules:
If a function would return void, the async version returns Task. If the function would return TResult, the async version should return Task<TResult>.
There is one exception: the async event handler returns void.
The return value of await Task is void. The return value of await Task<TResult> is TResult.
Only async functions can call other async functions.
If you have a non-async function you can still use the async function. However you cannot use await. Use the Task return value of the async function and the System.Threading.Tasks.Task methods to wait for the results.
If you have an async function and want to start a non-async function in a separate thread, use:
private int SlowCalculation(int a, int b)
{
System.Threading.Thread.Sleep(TimeSpan.FromSeconds(5));
return a + b;
}
private async Task CalculateAsync(int a, int b)
{
Task myTask = Task.Run( () => SlowCalculation(a, b);
// while SlowCalcuation is calculating slowly, do other useful things
// after a while you need the answer
int sum = await myTask;
return sum;
}
See that the return of await Task<int> is int.
Some people used to use functions like Task.ContinueWith. Because of the await statement that is not needed anymore. Await makes sure that the task is finished. The statement after the await is what you'd normally do in the ContinueWith.
In Task.ContinueWith you could say: "do this only if the task failed". The async-await equivalent for this is try-catch.
Remember: if your thread has nothing useful to do (like keeping your UI responsive), don't use async-await
Starting several tasks in async-await and waiting for them to finish is done as follows:
private async Task MyAsyncFunction(...)
{
var tasks = new List<Task<int>>();
for (int i=0; i<10; ++i)
{
tasks.Add(CalculateAsync(i, 2*i);
}
// while all ten tasks are slowly calculating do something useful
// after a while you need the answer, await for all tasks to complete:
await Task.WhenAll(tasks);
// the result is in Task.Result:
if (task[3].Result < 5) {...}
}
The async-await version of Task.Waitall is Task.WhenAll. WhenAll returns a Task instead of void, so you can await for it. The main thread remains responsive even while awaiting.
The main thread is not the case when using Task.WaitAll, because you don't await.
We have a WCF service with methods and their asyncs, we want to call them async.
The following code hangs up:
private void btnRunTest_Click(object sender, EventArgs e)
{
Task<List<DtoEmployee>> resultOfLoadEmployees = LoadEmployeesAsync(predicateEmployee1); // hangs up on this line
resultOfLoadEmployees.Wait();
var employeeList = resultOfLoadEmployees.Result;
foreach (var item in employeeList)
{
//Do Something
}
}
private async Task<List<DtoEmployee>> LoadEmployeesAsync(int employeeNumber)
{
return await _serviceClient.EmployeeGetListAsync(employeeNumber);
}
but the following code is OK and runs without a problem:
private async Task<List<DtoEmployee>> LoadEmployeesAsync(int employeeNumber)
{
return await _serviceClient.EmployeeGetListAsync(employeeNumber);
}
private async void btnRunTest_Click(object sender, EventArgs e)
{
List<DtoEmployee> employeeList = await LoadEmployeesAsync(employeeNumber);
foreach (var item in employeeList)
{
//Do Something
}
}
What's the differences and which one is correct to call async WCF method?
What's the differences and which one is correct to call async WCF
method?
That difference is that the former deadlocks here:
resultOfLoadEmployees.Wait();
A synchronization context is trying to marshal the continuation work back (everything after your first await) but can't because it's blocked via a Wait() call, which synchronously blocks. The latter properly asynchronously waits on the result to return, while not blocking the call. That's why you shouldn't block no async code
You should use the latter.
Side note - you can save yourself the state-machine generation as you can simply return the hot task created by EmployeeGetListAsync:
private Task<List<DtoEmployee>> LoadEmployeesAsync(int employeeNumber)
{
return _serviceClient.EmployeeGetListAsync(employeeNumber);
}
I've used async coding a little bit but I don't really fully understand how to use it -- though I understand the concept and why I need it.
Here's my set up:
I have a Web API that I will call from my ASP.NET MVC app and my Web API will call DocumentDB. In code samples, I see a lot of await keywords while sending queries to DocumentDB.
I'm confused if I need to make my Index action method in my MVC app async?
I'm also confused if my CreateEmployee() method in my Web API should be async?
What is the right way to use async in this scenario?
Here's my code (This code is currently giving me errors because my MVC action method is not async)
---- ASP.NET MVC App Code ----
public ActionResult Index()
{
Employee emp = new Employee();
emp.FirstName = "John";
emp.LastName = "Doe";
emp.Gender = "M";
emp.Ssn = "123-45-6789";
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("http://myWebApi.com");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await client.PostAsJsonAsync("hr/create/newemployee", emp);
if (response.IsSuccessStatusCode)
{
emp = await response.Content.ReadAsAsync<Employee>();
}
}
// Display employee info
return View(emp);
}
---- Web API Code ----
private static readonly string endPointUrl = ConfigurationManager.AppSettings["EndPointUrl"];
private static readonly string authorizationKey = ConfigurationManager.AppSettings["AuthorizationKey"];
private static readonly string databaseId = ConfigurationManager.AppSettings["DatabaseId"];
private static DocumentClient client;
public static async Task<Employee> CreateEmployee(Employee emp)
{
try
{
//Create a Document client
using (client = new DocumentClient(new Uri(endPointUrl), authorizationKey))
{
//Get the database
var database = await GetDatabaseAsync();
//Get the Document Collection
var collection = await GetCollectionAsync(database.SelfLink, "Employees");
await client.CreateDocumentAsync(collection.SelfLink, emp);
// Further process employee
}
}
catch
{
// Handle error
}
return employee;
}
private static async Task<DocumentCollection> GetCollectionAsync(string dbLink, string id)
{
DocumentCollection collection = client.CreateDocumentCollectionQuery(dbLink).Where(c => c.Id == id).ToArray().FirstOrDefault();
return collection;
}
private static async Task<Database> GetDatabaseAsync()
{
Database database = client.CreateDatabaseQuery().Where(db => db.Id == databaseId).ToArray().FirstOrDefault();
return database;
}
Here's my explanation
class MainClass
{
public static async Task<String> AsyncMethod(int delay) {
await Task.Delay (TimeSpan.FromSeconds(delay));
return "The method has finished it's execution after waiting for " + delay + " seconds";
}
public static async Task Approach1(int delay)
{
var response = await AsyncMethod (delay); // await just unwraps Task's result
Console.WriteLine (response);
}
public static Task Approach2(int delay)
{
return AsyncMethod(delay).ContinueWith(message => Console.WriteLine(message)); // you could do the same with
}
public static void Main (string[] args)
{
var operation1 = Approach1 (3);
var operation2 = Approach2 (5);
Task.WaitAll (operation1, operation2);
Console.WriteLine("All operations are completed")
}
}
Eventually both Approach1 and Approach2 are identical pieces of code.
The async/await is syntactic sugar around Task API. It takes your async method splits it into parts before await, and after await. The "before" part is executed immediately. The "after" part is getting executed when await operation is completed. You are able to track the second part of operation via the Task API since you get a reference to a Task.
In general async allows to treat a method call as a some sort of long operation that you can reference via the Task API and wait until it is finished and continue with another piece of code. Either via ContinueWith call of via using await in general it's the same.
Before async/await/Task concepts people were using callbacks, but handling errors was as easy as hell, the Task is similar to a concept of callback except that it is able allow handling exceptions more easily.
In general all this Task/async/await mantra is close to concept of promises if it happen that you've worked with jQuery/JavaScript there's a similar concept here's a nice question explaining how it's done there "jQuery deferreds and promises - .then() vs .done()"
Edit: I've just found out that .NET lacks implementation of then functionality similar to one found in jQuery/JavaScript.
The difference between ContinueWith and Then is that Then is able to compose task, and to execute them sequentially while ContinueWith is not, it is able only to launch task in parallel, but it can be easily implemented via the await construct. Here is my updated code containing the whole shebang:
static class Extensions
{
// Implementation to jQuery-like `then` function in .NET
// According to: http://blogs.msdn.com/b/pfxteam/archive/2012/08/15/implementing-then-with-await.aspx
// Further reading: http://blogs.msdn.com/b/pfxteam/archive/2010/11/21/10094564.aspx
public static async Task Then(this Task task, Func<Task> continuation)
{
await task;
await continuation();
}
public static async Task<TNewResult> Then<TNewResult>(
this Task task, Func<Task<TNewResult>> continuation)
{
await task;
return await continuation();
}
public static async Task Then<TResult>(
this Task<TResult> task, Func<TResult,Task> continuation)
{
await continuation(await task);
}
public static async Task<TNewResult> Then<TResult, TNewResult>(
this Task<TResult> task, Func<TResult, Task<TNewResult>> continuation)
{
return await continuation(await task);
}
}
class MainClass
{
public static async Task<String> AsyncMethod1(int delay) {
await Task.Delay (TimeSpan.FromSeconds(delay));
return "The method has finished it's execution after waiting for " + delay + " seconds";
}
public static Task<String> AsyncMethod2(int delay)
{
return Task.Delay (TimeSpan.FromSeconds (delay)).ContinueWith ((x) => "The method has finished it's execution after waiting for " + delay + " seconds");
}
public static async Task<String> Approach1(int delay)
{
var response = await AsyncMethod1 (delay); // await just unwraps Task's result
return "Here is the result of AsyncMethod1 operation: '" + response + "'";
}
public static Task<String> Approach2(int delay)
{
return AsyncMethod2(delay).ContinueWith(message => "Here is the result of AsyncMethod2 operation: '" + message.Result + "'");
}
public static void Main (string[] args)
{
// You have long running operations that doesn't block current thread
var operation1 = Approach1 (3); // So as soon as the code hits "await" the method will exit and you will have a "operation1" assigned with a task that finishes as soon as delay is finished
var operation2 = Approach2 (5); // The same way you initiate the second long-running operation. The method also returns as soon as it hits "await"
// You can create chains of operations:
var operation3 = operation1.ContinueWith(operation1Task=>Console.WriteLine("Operation 3 has received the following input from operation 1: '" + operation1Task.Result + "'"));
var operation4 = operation2.ContinueWith(operation2Task=>Console.WriteLine("Operation 4 has received the following input from operation 2: '" + operation2Task.Result + "'"));
var operation5 = Task.WhenAll (operation3, operation4)
.Then(()=>Task.Delay (TimeSpan.FromSeconds (7)))
.ContinueWith((task)=>Console.WriteLine("After operation3 and 4 have finished, I've waited for additional seven seconds, then retuned this message"));
Task.WaitAll (operation1, operation2); // This call will block current thread;
operation3.Wait (); // This call will block current thread;
operation4.Wait (); // This call will block current thread;
operation5.Wait (); // This call will block current thread;
Console.WriteLine ("All operations are completed");
}
}
you can only use await inside a method if that method is async and async methods need to return Task, Task<T> or void although void returning async methods are reserved for event handlers because the exceptions thrown within them are swallowed and you cannot await their completion or chain subsequent tasks.
I think your Index action needs to be async and return a Task<ActionResult> and your CreateEmployee method needs to be async as well as it is using await inside it.
See Best Practices in Asynchronous Programming for some guidelines on when and how to use async-await
async await
They are tricky to understand.
First of all, in your methods in Web API, you are using async without await. I'm sure you are getting some errors / warning there right?
--
async await are used to return the working thread back to the caller when you are waiting for I/O to be finished. So, yes, you do want to use it both in your MVC and Web API side. Please make sure you understand this sentence before moving on.
--
The thing about async / await is that, if you use it, you have to use it ALL the way through the calling functions, or else it doesn't make sense (and you'll get errors / warning too). This means that whatever library you are using must support it. In this case "DocumentClient". By convention, the methods that support it will end in "Async" and it will return a Task which you can await.
--
So your short answer:
use async await from the very beginning (your controller), and try to make it await whatever long operations it calls. If that is also your code, you should be able to await from there ... and await from there ... until you finally call something that is not your code. If you can await that code that is not yours, then you are set. If you cannot, then you should not use async await form the very beginning.
(no way this made sense)