Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WhenAll() not working as expected

I need to make UI thread wait until a task array completes execution.The problem with below code is that - the tasks inturn invoke UI thread to write into textbox. How to fix this?

public partial class FormConsole : Form
{
    public FormConsole()
    {
        InitializeComponent();
    }
    void txtSayHello_Click(object sender, EventArgs e)
    {
        Class1 objclss = new Class1();
        objclss.formConsole = this;

        Task[] taa = new Task[4];
        taa[0] = new Task(() => objclss.DoSomeThigs("Hello world"));
        taa[1] = new Task(() => objclss.DoSomeThigs("Hello world1"));
        taa[2] = new Task(() => objclss.DoSomeThigs("Hello world2"));
        taa[3] = new Task(() => objclss.DoSomeThigs("Hello world3"));

        foreach(Task task in taa)
        {
            task.Start();
        }
        Task.WhenAll(taa);
        this.txtConsole.AppendText("All threads complete");
    }

    delegate void doStuffDelegate(string value);

    public void doStuff(string value)
    {        
        if (System.Windows.Forms.Form.ActiveForm.InvokeRequired && IsHandleCreated)
        {
            BeginInvoke(new doStuffDelegate(doStuff), value);        
        }
        else
            txtConsole.AppendText(value);        
    }

}

public class Class1
{
    public FormConsole formConsole;
    public void DoSomeThigs(string sampleText)
    {
        formConsole.doStuff(sampleText);
    }
}

o/p now : Console Redirection TestAll threads completeHello worldHello world1Hello world2Hello world3

o/p I want : Console Redirection TestHello worldHello world1Hello world2Hello world3All threads complete

What's the solution?

like image 229
Murali Uppangala Avatar asked Feb 20 '26 10:02

Murali Uppangala


1 Answers

Task.WhenAll returns a task that completes when all tasks passed to it complete. You have to await this task, otherwise the method will continue executing.

async void txtSayHello_Click(object sender, EventArgs e)
{
    ...
    await Task.WhenAll(taa);
    ...
}

There is a blocking version of this method - Task.WaitAll. It will block the current thread until all tasks are done, but it's not a good idea to block the UI thread.

Also, the preferred way to start a task on a thread pool thread is to use Task.Run.

like image 79
Jakub Lortz Avatar answered Feb 23 '26 00:02

Jakub Lortz



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!