GetAsync : not returning HttpResponseMessage - c#

The apps should receive httpresponsemessage from LoginUser() but it becomes not responding.
private void button1_Click(object sender, EventArgs e)
{
if (LoginUser(tUser.Text, Password.Text).Result.IsSuccessStatusCode)
{
Notifier.Notify("Successfully logged in.. Please wait!");
}
else
{
Notifier.Notify("Please check your Credential..");
}
}
public async Task<HttpResponseMessage> LoginUser(string userid, string password)
{
string URI = "http://api.danubeco.com/api/userapps/authenticate";
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("c291cmF2OmtheWFs");
using (var response = await client.GetAsync(String.Format("{0}/{1}/{2}", URI, userid, password)))
{
return response;
}
}
}
Please help!

You are blocking the UI thread and causing a deadlock. From Stephen Cleary's blog (Just replace GetJsonAsync with your LoginUser method, and GetStringAsync with client.GetAsync):
So this is what happens, starting with the top-level method
(Button1_Click for UI / MyController.Get for ASP.NET):
The top-level method calls GetJsonAsync (within the UI/ASP.NET context).
GetJsonAsync starts the REST request by calling HttpClient.GetStringAsync (still within the context).
GetStringAsync returns an uncompleted Task, indicating the REST request is not complete.
GetJsonAsync awaits the Task returned by GetStringAsync. The context is captured and will be used to continue running the
GetJsonAsync method later. GetJsonAsync returns an uncompleted Task,
indicating that the GetJsonAsync method is not complete.
The top-level method synchronously blocks on the Task returned by GetJsonAsync. This blocks the context thread.
… Eventually, the REST request will complete. This completes the Task that was returned by GetStringAsync.
The continuation for GetJsonAsync is now ready to run, and it waits for the context to be available so it can execute in the context.
Deadlock. The top-level method is blocking the context thread, waiting for GetJsonAsync to complete, and GetJsonAsync is waiting for
the context to be free so it can complete.
And the simple available solutions (also from the blog):
In your “library” async methods, use ConfigureAwait(false) wherever possible.
Don’t block on Tasks; use async all the way down.
The 2nd solution suggests that you change button1_Click into:
private async void button1_Click(object sender, EventArgs e)
{
if ((await LoginUser(tUser.Text, Password.Text)).IsSuccessStatusCode)
{
Notifier.Notify("Successfully logged in.. Please wait!");
}
else
{
Notifier.Notify("Please check your Credential..");
}
}

Related

Is Async await Actually a blocking call?

private async Task<string> GetStateInfo()
{
var cityId = await GetCityIdByNameAsync("Delhi");
var state = await GetStateNameAsync(cityId);
return state;
}
As we know async and await are used for asynchronous programing and they are for non-blocking programming model. But in the code above the var state = await GetStateNameAsync(cityId); executes when the 1st line executes as it takes input from that.
So I dont understand is it a blocking call or non-blocking call?
Please see my async intro. await is an "asynchronous wait", so it "pauses" the method and returns an incomplete Task<string> instance. So the method is waiting for the task returned by GetCityIdByNameAsync to complete, but there is no thread blocked waiting for it.

ConfigureAwait and GetAwaiter changing behaviour

I'm experimenting with Tasks.
I have
private async Task<string> GetStringWithInnerCallConfigureAwaitFalseAsync()
{
await Task.Delay(3000).ConfigureAwait(false);
return "Finished!";
}
private async Task<string> GetStringAsync()
{
await Task.Delay(3000);
return "Finished!";
}
What's strange to me:
private void Button10_Click(object sender, RoutedEventArgs e)
{
Button10.Content = "GetAwaiter() GetResult() + deadlock";
var task = GetStringAsync().ConfigureAwait(false).GetAwaiter();
var result = task.GetResult(); // deadlock
Button10.Content = result;
}
I expected NO deadlock and crash on the last line because of non-UI context as it would be didn't I used GetAwaiter(), but I experience a deadlock
Next:
private void Button11_Click(object sender, RoutedEventArgs e)
{
Button11.Content = "GetAwaiter() GetResult() No deadlock";
var task = GetStringWithInnerCallConfigureAwaitFalseAsync().ConfigureAwait(false).GetAwaiter();
var result = task.GetResult(); // No deadlock
Button11.Content = result; // No crash
}
Here I expected crash on the last line because of non-UI context, but it works without issues.
Doesn't ConfigureAwait(false) make sense when we use GetAwaiter()?
ConfigureAwait configures the behaviour of the await keyword in the same expression. It does not affect other await statements in other methods, and it has no effect if you do not use await.
It controls whether the await statement captures the current SynchronizationContext (if there is one). In practice, if you run an await statement on the UI thread, then await task; will run the code after the await on the UI thread as well, whereas await task.ConfigureAwait(false) will run the code after the await on a ThreadPool thread.
In your first example:
private async Task<string> GetStringWithInnerCallConfigureAwaitFalseAsync()
{
await Task.Delay(3000).ConfigureAwait(false);
return "Finished!"; // <-- Run on the thread pool
}
private async Task<string> GetStringAsync()
{
await Task.Delay(3000);
return "Finished!"; // <-- Run on the captured SynchronizationContext (if any)
}
There is a difference in behaviour here, and that is which thread the return statement is run on.
In the first method, when the Task being awaited completes, a message is posted to the thread pool, which runs the return statement.
In the second method, the await statement captures the current SynchronizationContext (which refers to the UI thread), and uses this to run the return statement on. This means that a message is posted to the UI thread when 3 seconds have elapsed, telling it to run that return statement.
In your first snippet which calls GetStringAsync:
var task = GetStringAsync().ConfigureAwait(false).GetAwaiter();
The call to ConfigureAwait does nothing here, because you're not awaiting the result. You can remove it with no change.
var result = task.GetResult(); // deadlock
The UI thread is needed to run the return statement in GetStringAsync. Since you've blocked it in the call to GetResult(), it can't finish the GetStringAsync method, and so you've got a deadlock.
In your second snippet which calls GetStringWithInnerCallConfigureAwaitFalseAsync:
var task = GetStringWithInnerCallConfigureAwaitFalseAsync().ConfigureAwait(false).GetAwaiter();
Again, the call to ConfigureAwait(false) does nothing, because you're not awaiting the result.
var result = task.GetResult(); // No deadlock
This time, GetStringWithInnerCallConfigureAwaitFalseAsync does await ...ConfigureAwait(false), and so the code after the await is run on the thread pool and not the UI thread. Therefore the UI thread isn't needed to complete this method, and so you can safely (!) block it.
Button11.Content = result; // No crash
You called this method on the UI thread, and you've never moved off it - you call everything synchronously, there are no awaits, etc. Therefore you're still on the UI thread at this point

Code after 'await Task.Delay(5000)' is not executing until the execution of relaycommand is completed

In my WPF application, i am calling relaycommand
private void AutoRun(object parameter)
{
for(int i=0;i<10;i++)
{
MoveLotCommand.Execute(0);
}
}
which inturns call another relay command
private void MoveLot(object parameter)
{
//Some Code
var Task = StartLotProcessing(currentAssemblyPlant);
}
}
and this relay command will call another async function
async Task StartLotProcessing(int currentAssemblyPlant)
{
await Task.Delay(5000);
var nextAssemblyPlant = currentAssemblyPlant + 1;
//Process after await
}
The issue is, my code after 'await Task.Delay(5000)' does not executes until my AutoRun() function execution is completed.
I am trying to execute the await async code for each variable in my for loop.
Any help would be appreciated and sorry for my explanation.
You are not calling the method correctly : you are missing the await operator to indicate that you have to wait, otherwise you effectively schedule the task but do not wait for it. The task is scheduled in a synchronous fashion, hence when your method returns.
Change your call to this, and the issue should go away:
await StartLotProcessing(currentAssemblyPlant);
The problem appears to be that you are calling StartLotProcessing asynchronously but not waiting for the task to complete before moving on.
Ideally you would call use async/await the whole way up the stack:
await MoveLotCommand.Execute(0);
...
await StartLotProcessing(currentAssemblyPlant);
If you're unable to do that, then you should call
var task = StartLotProcessing(currentAssemblyPlant);
...
task.Wait();

async wait leading to deadlock

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.

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

Categories