This question already has answers here:
Should I avoid 'async void' event handlers?
(4 answers)
Closed 1 year ago.
I need to assign async Task method to a multicastdelegate parameter as follows.
protected async Task GridRowSelect(Employee emp)
{
await Service.SetRowSelect(emp.Id);
}
gridSettings.RowSelect = new EventCallback<Employee>(this, (Action<Employee>)GridRowSelect);
But it gives an error.
'Task GridRowSelect(Employee) has the wrong return type'
If I change async Task to async void this is working. But is that the correct way?
Yes, async void is the correct way. The async void is intended specifically for making asynchronous event handlers possible. That's the whole reason for its existence. So using it for handling the RowSelect event is OK.
Related
This question already has an answer here:
Awaiting a Callback method
(1 answer)
Closed 1 year ago.
am using a synchronous 3rd function which I cannot modify, such as:
public void startDoSth(Action<string> onDone)
startDoSth spawn a new thread to do the job, and returns immediately, and when the thing is done, my onDone function would be called.
I'd like to write an asynchronous method like below to wrap it:
public async Task<string> doSthAsync();
So, someone can call it like this:
string s = await doSthAsync()
onDone(s)
In doSthasync() I call startDoSth() to do the real thing.
But I have no idea how to write the doSthAsync().
Could anyone tell if it is possible and how to do it? Thanks a lot.
You can use TaskCompletionSource to convert that into TAP:
Task<string> DoSthAsync()
{
var tcs = new TaskCompletionSource<string>();
startDoSth(tcs.SetResult);
return tcs.Task;
}
SetResult completes the returned Task (and sets the result), so that can be passed as the callback function.
This question already has answers here:
How and when to use ‘async’ and ‘await’
(25 answers)
Closed 5 years ago.
I have a third-party library which all methods are async and I have some questions
1) What is the difference between these two code lines?
Task.Run(async () => await MethodAsync());
Task.Run(() => PrepareDashBoard());
2) When I need to call an async method from an button click event which one is right?
// A.
private void Button_Click(object sender, EventArgs e)
{
//A Task Run call from questions 1) a or b with call to Wait or Result (if return something)
}
// B
private async void Button_Click(object sender, EventArgs e)
{
await MethodAsync();
}
TL;DR: Until you understand the implications do not mix directly using the task parallel library (Task<T> etc) with async and await (other than in the definition of async function return types).
To call an async function without a WinForms even handler just use
var res = await theFunction(args);
The WinForms runtime knows how to handle the thread management (so all GUI interactions stay on one thread).
Re. Q1:
a. Launches a new asynchronous task to call an async method asynchronously and is complete when the inner task starts running. This is extremely unlikely to be what you want.
b. Runs the lambda in an asynchronous task, the task is marked complete when the lambda completes.
PS. When C#5 was launched there were many articles covering the interaction of async and WinForms in far greater detail than is possible in an answer here.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
There is a method which will take a Task as input and await.
protected async Task DoTask(Task t)
{
//Do something
await t;
}
The second method will accept the method name in string format and will create the method object using Reflection. Task needs to be created instead of invoking it and pass it to first method
This two methods are part of a base class . The child class which is a view model will call DoTask2 and pass the name of the function defined inside itself(i.e.view model).
protected async Task DoTask2(string method)
{Task t = null;
var typeInfo = this.GetType().GetTypeInfo();
var methods = typeInfo.DeclaredMethods;
var meth = methods .Single(o => String.Equals(o.Name, method));
t = meth .Invoke(this, null) as Task;
await DoTask(t);
}
But this is not working properly. Is something wrong here in the approach.
I am trying to build this in a windows 8.1 store app
EDIT:
Upon executing this line, instead getting the Task object, the async method is getting invoked. I need to get the task so that I can pass it to the next method.
.
I want to get the method using reflection but create it as a new Task execute using my doTask method. All methods are in the same class. Dotask and Dotask2 are in the base class.
I think the main problem here is one of expectation;
I want to get the method using reflection but create it as a new Task execute using my doTask method.
That simply isn't how most async APIs work; invoking an async method: is executing an async method - or more specifically, it is executing the method as far as the first continuation that reports as incomplete. Invoking an async method does not just create an as-yet unstarted token to a method. I wonder if you might actually want a Func<Task> rather than a Task - a Func<Task> is a delegate that returns a Task when invoked - but without invoking it yet. There are ways to create a Func<T> directly from a MethodInfo in regular .NET, but in windows-store apps you might need to be indirect:
Func<Task> invoker = () => (Task)meth.Invoke(this, null);
You would then have:
private async Task DoTask(Func<Task> invoker)
{
var t = invoker(); //Do something code goes somewhere in this method
await t;
}
This question already has answers here:
Catch an exception thrown by an async void method
(6 answers)
Closed 9 years ago.
I have a simplistic structure and I have a hard time understanding why it works (or does not work) how I think it should work.
Basically, there are two methods
private async void DoStuff()
{
try {
AuthenticationStuff();
}catch(UnauthorizedAccessException){
UI.Display("AMAGAD!");
}
}
private async void AuthenticationStuff()
{
var user = GetUser();
if(user == null) throw new UnauthorizedAccessException();
DoMoreAuthenticationStuff();
}
Now the problem is that the exception never reaches DoStuff() method's handler. My first instinct was that "hey, it's an async method, I have to await it", but I can't do that either as apparently async void is different from async Task<void>.
I am trying to understand what's going on in here. Why isn't the exception going to the handler, but instead the debugger breaks at "DoMoreAuthenticationStuff()" with an unhandeled exception error?
Exceptions raised by an async void method go directly to the SynchronizationContext that was active at the time the method started. This is one of the reasons why you should avoid async void. I cover this and other reasons in my MSDN article Best Practices in Asynchronous Programming.
To catch exceptions like this, change your async void method to async Task and await the returned task.
My first instinct was that "hey, it's an async method, I have to await
it", but I can't do that either as apparently async void is different
from async Task.
You can just say async Task MyMethod(). Then you can await its result to propagate the exception (and to wait for completion).
Also observe Stephen Cleary's answer for more details.
This question already has answers here:
Can't specify the 'async' modifier on the 'Main' method of a console app
(20 answers)
Closed 5 years ago.
I'm trying to make a simple program to test the new .NET async functionality within Visual Studio 2012. I generally use BackgroundWorkers to run time-consuming code asynchronously, but sometimes it seems like a hassle for a relatively simple (but expensive) operation. The new async modifier looks like it would be great to use, but unfortunately I just can't seem to get a simple test going.
Here's my code, in a C# console application:
static void Main(string[] args)
{
string MarsResponse = await QueryRover();
Console.WriteLine("Waiting for response from Mars...");
Console.WriteLine(MarsResponse);
Console.Read();
}
public static async Task<string> QueryRover()
{
await Task.Delay(5000);
return "Doin' good!";
}
I checked out some examples on MSDN and it looks to me like this code should be working, but instead I'm getting a build error on the line containing "await QueryRover();" Am I going crazy or is something fishy happening?
You can only use await in an async method, and Main cannot be async.
You'll have to use your own async-compatible context, call Wait on the returned Task in the Main method, or just ignore the returned Task and just block on the call to Read. Note that Wait will wrap any exceptions in an AggregateException.
If you want a good intro, see my async/await intro post.