I've followed the following example which works well.
https://developer.xamarin.com/guides/cross-platform/application_fundamentals/web_services/walkthrough_working_with_WCF/
The only issue is, the example uses button clicks to load data. Now i have two separate calls different functions, and i need one to wait for the other, for example:
So when i call function2 for example, i want to wait for function1 first.
_client.function1Async();
_client.function2Async();
I could put the function2 call inside the function1Completed handler, but i was looking to use async wait with it. When i use async task, i get an error saying cannot await a void. But the web service async function in the example is a void
If i had 6 calls that i wanted to run, it would become very messy.
void _client_function1Completed(object sender,UpdateOrdersByWardCompletedEventArgs e
{
}
void _client_function2Completed(object sender,UpdateOrdersByWardCompletedEventArgs e
{
}
Hope this makes sense.
You could Task.ContinueWith
ContinueWith creates a continuation that executes asynchronously when task 1 completes.
var task1 = Task.Factory.StartNew( () => { func1(); } );
Task task2 = task1 .ContinueWith( (i) => { func2(); } );
Not sure if I understood well what you are trying to achieve, but I guess you can try something like this:
Given some lengthy (and blocking) methods:
public void func1()
{
Console.WriteLine("func1");
System.Threading.Thread.Sleep(5000);
}
public void func2()
{
Console.WriteLine("func2");
System.Threading.Thread.Sleep(5000);
}
You could add the ability to run the lengthy stuff asynchronously by doing this:
public async Task function1Async()
{
await Task.Run(() => {
func1();
});
}
public async Task function1Async()
{
await Task.Run(() => {
func2();
});
}
Now you can choose to run 'func1' and 'func2' either asynchronously or synchronously, for example:
function1Async().Wait(); // will block
function2Async(); // will run asynchronously
So, for your particular case, given that you already have the two async methods, I guess that all you need to do is to call them as shown above.
Related
I have the following four tests and the last one hangs when I run it. Why does this happen:
[Test]
public void CheckOnceResultTest()
{
Assert.IsTrue(CheckStatus().Result);
}
[Test]
public async void CheckOnceAwaitTest()
{
Assert.IsTrue(await CheckStatus());
}
[Test]
public async void CheckStatusTwiceAwaitTest()
{
Assert.IsTrue(await CheckStatus());
Assert.IsTrue(await CheckStatus());
}
[Test]
public async void CheckStatusTwiceResultTest()
{
Assert.IsTrue(CheckStatus().Result); // This hangs
Assert.IsTrue(await CheckStatus());
}
private async Task<bool> CheckStatus()
{
var restClient = new RestClient(#"https://api.test.nordnet.se/next/1");
Task<IRestResponse<DummyServiceStatus>> restResponse = restClient.ExecuteTaskAsync<DummyServiceStatus>(new RestRequest(Method.GET));
IRestResponse<DummyServiceStatus> response = await restResponse;
return response.Data.SystemRunning;
}
I use this extension method for restsharp RestClient:
public static class RestClientExt
{
public static Task<IRestResponse<T>> ExecuteTaskAsync<T>(this RestClient client, IRestRequest request) where T : new()
{
var tcs = new TaskCompletionSource<IRestResponse<T>>();
RestRequestAsyncHandle asyncHandle = client.ExecuteAsync<T>(request, tcs.SetResult);
return tcs.Task;
}
}
public class DummyServiceStatus
{
public string Message { get; set; }
public bool ValidVersion { get; set; }
public bool SystemRunning { get; set; }
public bool SkipPhrase { get; set; }
public long Timestamp { get; set; }
}
Why does the last test hang?
Acquiring a value via an async method:
var result = Task.Run(() => asyncGetValue()).Result;
Syncronously calling an async method
Task.Run( () => asyncMethod()).Wait();
No deadlock issues will occur due to the use of Task.Run.
You're running into the standard deadlock situation that I describe on my blog and in an MSDN article: the async method is attempting to schedule its continuation onto a thread that is being blocked by the call to Result.
In this case, your SynchronizationContext is the one used by NUnit to execute async void test methods. I would try using async Task test methods instead.
You can avoid deadlock adding ConfigureAwait(false) to this line:
IRestResponse<DummyServiceStatus> response = await restResponse;
=>
IRestResponse<DummyServiceStatus> response = await restResponse.ConfigureAwait(false);
I've described this pitfall in my blog post Pitfalls of async/await
You are blocking the UI by using Task.Result property.
In MSDN Documentation they have clearly mentioned that,
"The Result property is a blocking property. If you try to access it
before its task is finished, the thread that's currently active is
blocked until the task completes and the value is available. In most
cases, you should access the value by using Await or await instead of
accessing the property directly."
The best solution for this scenario would be to remove both await & async from methods & use only Task where you're returning result. It won't mess your execution sequence.
An addition to the answer given by #HermanSchoenfeld. Unfortunately the quote below is not true:
No deadlock issues will occur due to the use of Task.Run.
public String GetSqlConnString(RubrikkUser user, RubrikkDb db)
{
// deadlock if called from threadpool,
// works fine on UI thread, works fine from console main
return Task.Run(() =>
GetSqlConnStringAsync(user, db)).Result;
}
The execution is wrapped inside a Task.Run, this will schedule the task on the threadpool the block the calling thread. This is okay, as long as the calling thread is not a threadpool thread. If the calling thread is from the threadpool then the following disaster happens: A new task is queued to the end of the queue, and the threadpool thread which would eventually execute the Task is blocked until the Task is executed.
In library code there is no easy solution as you cannot assume under what context your code is called. The best solution is to only call async code from async code, blocking sync APIs from sync methods, don’t mix them.
Source:
https://medium.com/rubrikkgroup/understanding-async-avoiding-deadlocks-e41f8f2c6f5d
If you don't get any callbacks or the control hangs up, after calling the service/API async function, you have to configure Context to return a result on the same called context.
Use TestAsync().ConfigureAwait(continueOnCapturedContext: false);
You will be facing this issue only in web applications, but not in static void main.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I have a complex method, this method make webRequest, access database and other jobs.
public string MyComplexMethod(params){
//Access db
//Make WebRequests
//...
}
I made this method asynchronous this way:
public async Task<string> MyComplexMethod(params)
{
//Access db
//Make WebRequests
//...
}
public async Task MyComplexMethodAsync(params)
{
await Task.Run(() => MyComplexMethod()).ConfigureAwait(false);
}
And I call my complex method this way:
public void OtherMethod()
{
//other stuff
MyComplexMethodAsync(params);
//other stuff
}
Can I use async and mainly Task.Run with such complex method?
Or there another way to make this method asynchronous?
To be wrapped by Task.Run method don't need to be asynchronous
public string MyComplexMethod() {}
public Task MyComplexMethodAsync()
{
return Task.Run(() => MyComplexMethod());
}
But using sample above don't make your method to be asynchronous in the way async-await works.
You mentioned that your complex method uses webservices and database queries - this makes your method to be perfect candidate for making it asynchronous.
async-await was designed mostly for working with external resources effectively without using extra threads for operations which only waiting for response and do nothing.
Only you need, it creates own asynchronous method for every operation which "touches" external resources, most of the "clients" already provide asynchronous methods for working with databases or web services.
// Access Db
public async Task<object> GetValueFromDatabaseAsync()
{
using (var connection = new SqlConnection(connectionString))
using (var command = new SqlCommand(query, connection))
{
await connection.OpenAsync();
return await command.ExecuteScalarAsync();
}
}
// Make web request
public async Task<HttpResponseMessage> SendRequestToWebServiceAsync(SomeData data)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(webserviceUrl);
return await client.PostAsJsonAsync("api/values", data);
}
}
Then you end up with your asynchronous complex method
public async Task<string> MyComplexMethodAsync()
{
var value = await GetValueFromDatabaseAsync();
var data = new SomeData(value);
var response = await SendRequestToWebServiceAsync(data);
return response.StatusCode.ToString();
}
Interesting part of asynchronous approach, that after you starting using async-await methods in your application they starts spreading over whole application like a zombies :)
For using MyComplexMethodAsync yuo need change OtherMethod to be asynchronous too
public async Task OtherMethodAsync()
{
//other stuff
await MyComplexMethodAsync(params);
//other stuff
}
I think you're on the right path with async / await.
async tells the compiler that you are going to wrap everything in that method ContinueWith AFTER you reach the await keyword.
public void Something()
{
var task = new Task(() => DoWork());
task.ContinueWith(() => MoreWorkAfter());
task.Start();
}
//Is the same as
public async void Something()
{
var task = new Task(() => DoWork());
task.Start();
await Task;
MoreWorkAfter();
}
//Is also the same as
public async void Something()
{
var task = Task.Run(() => DoWork());
await Task;
MoreWorkAfter();
}
//Still the same as
public async void Something()
{
await Task.Run(() => DoWork());
MoreWorkAfter();
}
To make the method itself awaitable it has to return a Task object also because Task has the GetAwaiter() the await is looking for. Just remember that if you don't START the task it will await forever. So here's the same method written in an awaitable way for others.
public Task SomethingAsync()
{
return Task.Run(() => DoWork());
}
//Same as...
public async Task SomethingAsync()
{
await Task.Run(() => DoWork());
}
//And now in other methods you can....
public async void AnotherMethod()
{
await SomethingAsync();
//Do more work after it's complete.
}
Something to take away is that the Task is running on a new thread once it's started and to answer your question, yes it offloads the work. So for your original method keep it the same. The async method can Task.Run it like you've done.
public string MyComplexMethod(params)
{
//Access db
//Make WebRequests
//...
}
public async Task MyComplexMethodAsync(params)
{
await Task.Run(() => MyComplexMethod()).ConfigureAwait(false);
}
Something to note however; is that although you may call:
await MyComplexMethodAsync(params);
You have ConfigureAwait(false);
Which means any code after the task, in that method, will not be on the current context.
public async Task MyComplexMethodAsync(params)
{
//Main thread work here
await Task.Run(() => MyComplexMethod()).ConfigureAwait(false);//Background work here
//This will also be background work since CongfigureAwait(false);
}
public async Task MyComplexMethodAsync(params)
{
//Main thread work here
await Task.Run(() => MyComplexMethod()); //Background work here
//Main thread work here again since CongfigureAwait defaults to true;
}
And I say Main thread work but that assumes the Main thread called MyComplexMethodAsync.
The easiest way to grasp it is just imagine everything AFTER the await keyword is basically a new Action that gets called when the task is complete; just like using ContinueWith.
AND if there is code AFTER the await keyword in your method, it will BE SCHEDULED to run on the Main thread (considering the Main thread called the method to start with). Meaning it's a little like using Dispatcher.BeginInvoke if you've ever use it. The remaining portion get's queued to run on the Main thread in better terms. (Again, unless you put ConfigureAwait(false) and then it doesn't)
I'm programming an API for my software, which has a lot of interfaces and my software just inherits them.
I want the API users to have the possibility to do something after X milliseconds, something like this :
public void PerformAction(Action action, int delay)
{
Task.Run(async delegate
{
await Task.Delay(delai);
Form.BeginInvoke(action);
// I invoke on the Form because I think its better that the action executes in my main thread, which is the same as my form's thread
});
}
Now i know that the Task is like a new Thread, I just want to know, is this bad for my software? Is there any other possible better way?
The method will get executed a lot, so I don't know whether this approach is good or bad
You should not be creating a new Task for this, you can instead make the method a Task, something like this:
public async Task PerformAction(Action action, int delay)
{
await Task.Delay(delay);
action(); //this way you don't have to invoke the UI thread since you are already on it
}
And then simply use it like this:
public async void Butto1_Click(object sender, EventArgs e)
{
await PerformAction(() => MessageBox.Show("Hello world"), 500);
}
public async Task PerformAction(Action action, int delay)
{
await Task.Delay(delay);
action();
}
I'm currently trying to write async code and I have the feeling that my code is not too correct at all.
I have the following method:
public void Commit()
{
_context.SaveChangesToDatabase();
}
Don't judge the code here as this are only samples. Also, don't say that if I'm using Entity Framework, that they come packaged with Async methods already. I just want to understand the async concept here.
Let's say that the method SaveChangesToDatabase does takes seconds to complete.
Now, I don't want to wait for it so I create an async method:
public async Task CommitAsync()
{
await Task.Run(() => Commit());
}
Does this mean that if I have a method:
public void Method()
{
// Operation One:
CommitAsync();
// Operation Two.
}
Does this mean that my code on Operation two will be executed before CommitAsync() is even completed?
If not, please guide me in the right direction.
Update
Based on the remarks here that I'm ignoring my async method results, is this implementation better?
public Task<TaskResult> CommitAsync()
{
var task = new Task<TaskResult>(() =>
{
try { Commit(); }
catch (Exception ex)
{
return new TaskResult
{
Result = TaskExceutionResult.Failed,
Message = ex.Message
};
}
return new TaskResult { Result = TaskExceutionResult.Succeeded };
});
task.Start();
return task;
}
This does mean that I need to put the async modifier on the method that call this code so that I can await this which means continue with the current execution and return when this method has been completed.
Fire but don't forget
CommitAsync() returns a Task, but Method ignores the return value of CommitAsync completely -- so yes, the code will not wait but simply go on with what's after that. This is bad, because, if Commit() throws an exception, you will never see it. Ideally, every task should be waited on somewhere by someone, so you can at least see if it fails.
Let's say that you have no async alternative to SaveChangesToDatabase, but you'd like to use it in an async context anyway. You can use Task.Run to create a "fake-asynchronous" method, but this is not recommended (see below):
public Task CommitAsync() {
return Task.Run(() => Commit());
}
And then, assuming Method is doing something interesting with async (which the below code does not do since it's the only asynchronous operation in there):
public async Task MethodAsync() {
// Operation One:
await CommitAsync();
// Operation Two.
}
Assuming you do not want to wait, but you do want to do something if the task failed, you can use a separate method:
public void Method() {
// Operation One:
var _ = TryCommitAsync();
// Operation Two.
}
private async Task TryCommitAsync()
{
try
{
await CommitAsync();
}
catch (Exception ex)
{
Console.WriteLine(
"Committing failed in the background: {0}",
ex.Message
);
}
}
Getting back results
Let's suppose .Commit() does return something (like the number of records affected); a similar "fake-asynchronous" wrapper (again, not recommended - see below) would look like this:
public Task<int> CommitAsync() {
return Task.Run(() => Commit());
}
If you want this result, you can await the task immediately:
public async Task MethodAsync() {
// Operation One:
int recordsAffected = await CommitAsync();
// Operation Two.
}
Or, if you don't need it immediately, use await when you do:
public async Task MethodAsync() {
// Operation One:
Task<int> commit = CommitAsync();
// Operation Two.
// At this point I'd really like to know how many records were committed.
int recordsAffected = await commit;
}
Async: don't fake it
In general, you don't want to write wrappers like CommitAsync() because they mislead callers into thinking code will be asynchronous when it isn't really, which brings few benefits other than not blocking (which is still useful in UI code, but not as good as true asynchronous code which doesn't need to use worker threads for everything). In other words, you should use Task.Run in the invocation of a method, not as the implementation of a method.
So don't, as a habit, write wrappers like CommitAsync for every synchronous method you have -- instead you want to make a true CommitAsync that uses the async support of the underlying libraries/frameworks (SqlCommand.ExecuteReaderAsync(), etcetera.)
If you have no choice and must use Task.Run, then the appropriate usage would look more like:
// This method is in the UI layer.
public async Task MethodAsync() {
// Operation One:
// Commit() is a method in the DA layer.
await Task.Run(() => Commit());
// Operation Two.
}
Here
http://channel9.msdn.com/events/TechEd/NorthAmerica/2013/DEV-B318#fbid=
is a good explanation on how to work with async, and why you should avoid "async over sync", which is what you are doing now with
public Task CommitAsync() {
return Task.Run(() => Commit());
}
There are some scenarios where you can benefit from it, but if you are going to provide this as part of a library is NOT a good idea to make this.
If this code is ONLY and ONLY going to be used by your app, and you are sure what you are doing and dont have a wawy to call async methods inside your async method, just do it
I am using MvvmLight and have implemented communication between some of my ViewModels using the MessengerInstance.Send(...) method. It works great!
Recently, though, I have moved from using Synchronous methods to async methods to retrieve data and it looks like this breaks messaging (probably because it executes on a different thread). For example:
public ICommand SomeCommand { get { return new RelayCommand(DoSomething); } }
private async void DoSomething(object obj)
{
//Used to be SomeWcfService.DoSomething(); with some logic afterward
await SomeWcfService.DoSomethingAsync().ContinueWith(task => { //Some logic after method completes });
MessengerInstance.Send(SomeDataToSend, MessageIdentifer.DoSomething);
}
Instead of using a continuation, just put it after the await:
private async void DoSomething(object obj)
{
//Used to be SomeWcfService.DoSomething(); with some logic afterward
var result = await SomeWcfService.DoSomethingAsync();
// .ContinueWith(task => { //Some logic after method completes });
// use result here!
MessengerInstance.Send(SomeDataToSend, MessageIdentifer.DoSomething);
}
If there is no result returned from DoSomethingAsync, you can just leave out the result, and put your code in place.
The continuation, as you wrote it, will not run on the same synchronization context. The await keyword is actually asynchronously waiting your continuation, not the async method from WCF, as well.
If your "some logic" is asynchronous, you can use await within that code, as well.