C# 4.5 Task Parallel in windows forms [duplicate] - c#

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.

Related

What is a good alternative to await Task.Run executing an asyncronous lambda?

I'm in the process of upgrading old code using BackgroundWorker. Following a series of articles from Stephen Cleary on this matter, I think the ideal substitute in this case is Task.Run().
Mine is a Windows Forms application. When a Form is constructed, different background operations are started and their results are collected in different event handlers, as per the BackgroundWorker pattern.
Now, my new methods follow the async/await pattern. I have some concerns about calling Task.Run() on an async methods.
private async void FormEventHandler(object sender, EventArgs e)
{
Task.Run(async () => await AwaitableLongRunningTask_1());
Task.Run(async () => await AwaitableLongRunningTask_2());
//...
}
AwaitableLongRunningTask_1 and _2 needs to be async, since the calls they makes within the method body are to async methods.
I can't call them in a simple await succession:
private async void FormEventHandler(object sender, EventArgs e)
{
await AwaitableLongRunningTask_1();
await AwaitableLongRunningTask_2();
//...
}
since they need to be started in parallel and they're obviously long running tasks spanning several seconds.
So my question is, do I need to refactor AwaitableLongRunningTasks to be non-async void, changing their internal behaviour like suggested here in "How to call asynchronous method from synchronous method"? Are there better options I'm missing?
Use Task.WhenAll
private async void FormEventHandler(object sender, EventArgs e)
{
await Task.WhenAll(
AwaitableLongRunningTask_1(),
AwaitableLongRunningTask_2());
}

Await doesn't block calling thread [duplicate]

This question already has answers here:
How and when to use ‘async’ and ‘await’
(25 answers)
How do yield and await implement flow of control in .NET?
(5 answers)
Brief explanation of Async/Await in .Net 4.5
(3 answers)
Closed 2 years ago.
I never had a good chance to go deep into async/await , so I have just a gist of what it does.
So I tried it in WinForms app like this:
private async void button2_Click(object sender, EventArgs e)
{
// In below line I understand the Task is created and scheduled to execute, which in this
// simple case means, that it executes right away asynchronously.
var task = Task.Factory.StartNew(() =>
{
Task.Delay(5000).Wait();
return 12;
});
// Here we wait for the task to finish, so we don't see MessageBox yet.
var res = await task;
MessageBox.Show("Result is :" + res);
}
My question is, since we are waiting on await I expected to block UI thread, since we can go any further in that thread (to the line with MessageBox). So UI thread actually stops on method with event hadnler.
But, to my surprise, windows is responsive and everything works very well, but I didn't expect that. Can anybody explain me what is going on?
After reading this post, I still have a doubt, if await is asynchronous and doesn't block UI thread in my example, why the thread doesn't proceed to next line with MessageBox? How the UI thread proceeds then?
Is good idea that code after await is just another Task, like in ContinueWith? But it comes back to UI context?
Async methods are a lot like generator methods. The compiler will split up your code at each await operator. A block of code is inserted to check if the task is already complete, in which case the method immediately continues. Or if the task is not complete, a callback is registered to continue execution later, and your method returns.
Returning early is the whole point of an async method.

Why does await not wait?

This is my actual code:
async Task getData()
{
Thread.Sleep(5000);
Console.WriteLine("Step 1");
using (HttpClient api = new HttpClient())
await api.GetAsync("http://google.com/").ContinueWith(
(getTask) =>
Console.WriteLine(getTask.Result.StatusCode);
);
Console.WriteLine("Step 2");
}
private void button1_Click(object sender, EventArgs e)
{
Task<Task> task = new Task<Task>(getData);
task.Start();
task.Wait();
Console.WriteLine("Step 3");
}
I get the following output:
Step 1
Step 3
OK
Step 2
Why does Step 3 not come after Step 2?
How do I get it to work in sequence, ie to return to the caller of getData only until everything in getData is done?
You should also mark you event handler as async
private async Task button1_Click(object sender, EventArgs e)
and await instead of Wait:
private async Task button1_Click(object sender, EventArgs e)
{
await getData();
Console.WriteLine("Step 3");
}
When we use the async/await pattern, we should go this way until the first method initiated it. Otherwise, by calling explicitly Wait or Result, we may run into deadlock issues. Furthermore, calling explicitly those methods you block the executing thread. So you drop the main benefit of using async/await, which is not blocking the executing thread and run on a separate thread some code and once this is done resume the execution of your code from where you stopped.
To try and put things simply and clearly - async Task (and <T>) methods are, themselves, responsible for allocating a Task object which represents their completion.
If you find yourself working with async methods and allocating Task objects yourself (either directly, as here, or using static factory methods such as Task.Run), you've got to recognize that more than one Task object now exists. You have to be careful and recognize situations where (as here) you create Tasks that themselves now return Tasks.
It's far better, if possible, to embrace async all the way (as you modify each function to be async, you'll then tend to locate each call site and make that location async as well) and to stop allocating any Tasks yourself.

Multithreading in Windows Phone 8.1

public MainPage()
{
Method_1();
Method_2();
Method_3();
Method_4();
Method_5();
Method_6();
}
I am writing a Windows Phone 8.1 App (WINRT XAML). How to make these methods execute at a time from constructor? What I mean to ask is about multithreading, i want these methods to get executed sidebyside and not one after another.
Does this effect loading of application? will app load fast/slow?
First off, you don't want to execute those methods in the constructor if they are long running methods. Wait until the page is loaded:
private async void Page_Loaded(object sender, RoutedEventArgs e)
{
Task m1task = Method_1();
Task m2task = Method_2();
Task m3task = Method_3();
Task all = Task.WhenAll(m1Task, m2Task, m3Task);
await all;
}
The code will load off these operations to another thread and as long as your methods are properly implemented your UI will stay responsive (so don't use wait() for instance).
This is what a sample method could look like:
private async Task Method_1() {
// Long running operation goes here
}
If you have some heavy computations to do, wrap them into Task.Run(() => { // Code });It's really essential that you're aware of the concepts of asynchronous programming. You might want to read on here:
Do you have to put Task.Run in a method to make it async?
await vs Task.Wait - Deadlock?
When correctly use Task.Run and when just async-await
But seriously, you're writing that your methods are not UI related. You might be better off running those somewhere else (e.g. in your ViewModels or even in a background task / service).
Mark the methods as Async with return type Task.
eg. public async Task method1(){}
You won't be able to fire any UI activities from them, but they'll run outside of the main thread.

Label takes long time to change [duplicate]

This question already has an answer here:
Label won't change color until after code is finished executing
(1 answer)
Closed 8 years ago.
I have a problem with my winform app in C#.
In program, i have a label as statusbar and a method like this:
private void btnProcess_Click(object sender, EventArgs e)
{
lblStatus.Text = "Please wait...";
/*
Code here
*/
}
my code process taking a few second but after processing the code, text of label will change and i want it happening before that.
Note: I am an amateur in programming and i cant understand english very well, please explain your solution simply. thank you.
You may be able to hack this using a repaint event by calling Update or Refresh, but the real solution is using a BackgroundWorker for longer operations.
This is not easy stuff, you should find a tutorial for it in a language you understand perfectly.
In winform application (but also in all GUI application) it's not recommended execute long task in the GUI thread. For solving your problem you must use Thread(here you can find the complete mdsn reference).
If you want update the Label from another Thread you' ll do a Cross threading operation. For more information take a look to this question
All the code is always ran and completed before any changes are made to the UI. This is just the basic logic of WinForms and WPF.
You can use "BackgroundWorker", so the longer code is run on another thread. This way you can freely edit the UI-elements while the longer code is still running.
If you are using .Net 4.5, you can use await and async rather than BackgroundWorker.
You would create an async method that returns a Task, and inside that method use Task.Run() to start the background work.
Here's an example. You'd do all the slow work in the lambda passed to Task.Run() where I've commented "Do all your slow work here":
private async void btnProcess_Click(object sender, EventArgs e)
{
lblStatus.Text = "Please wait...";
await doSomeWorkAsynchronously();
lblStatus.Text = "Work completed";
}
private async Task doSomeWorkAsynchronously()
{
await Task.Run(()=>
{
// Do all your slow work here.
Thread.Sleep(5000); // Simulate slow work.
});
}
I think this is a bit easier than using BackgroundWorker.
Note that if all your "slow" methods were already async (e.g. if you are using asynchronous file I/O) then you might just be able to await each of your async operations rather than having to create your own task via Task.Run().
You can also return a value from the background task. Suppose you wanted to return a string with which to update the label when the background task had completed. You could do that as follows:
private async void btnProcess_Click(object sender, EventArgs e)
{
lblStatus.Text = "Please wait...";
lblStatus.Text = await doSomeWorkAsynchronously();
}
private async Task<string> doSomeWorkAsynchronously()
{
return await Task.Run(()=>
{
// Do all your slow work here.
Thread.Sleep(5000); // Simulate slow work.
return "The task completed.";
});
}

Categories