0

No work await Task.Run():

private async void button2_Click(object sender, EventArgs e)
{
    await Task.Run(() => {
        monitor_r(label1);
    });
}

protected async Task monitor_r(Label L1)
{
    MessageBox.Show(L1.Name);
    L1.ForeColor = Color.Blue;
    L1.Text = "test";
}

These commands

MessageBox.Show(L1.Name); 

and

L1.ForeColor = Color.Blue;  

works fine but

L1.Text = "test"; 

does not work.

Can you help, why do not change a Label Text?

Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
Mike
  • 9
  • 2
  • Why is `monitor_r` async? You don't await anything so it could just be `void`. – juharr Nov 01 '18 at 11:49
  • 1
    `does not work.` @Mike it may be helpful for you to give a bit more detail as to what `does not work` means. Was an exception thrown, for example (and if so, which one)? – mjwills Nov 01 '18 at 12:29

3 Answers3

4

Try Control.Invoke: we should run Winform UI in the main thread only

protected async Task monitor_r(Label L1)
{
    Action action = () => 
    {
        MessageBox.Show(L1.Name);

        L1.ForeColor = Color.Blue;
        L1.Text = "test";
    };

    if (L1.InvokeRequired)
        L1.Invoke(action); // When in different thread
    else 
        action();          // When in the main thread
}
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
1

If you're on debug mode, take a look at the output window. It should shows exception message something like this:

System.InvalidOperationException' in System.Windows.Forms.dll.

That because label1 accessed from a thread other than the thread it was created on. And it will causing invalid cross-thread operation.

You can solve this by using Control.Invoke as Dmitry Bychenko already mentioned. Here is simple extension to make thread-safe calls to Winforms Control.

public static void TryInvoke(this Control control, Action<Control> action)
{
      if (control.InvokeRequired) control.Invoke(new Action(() => action(control)));
      else action(control);
}

Sample usage

label1.TryInvoke(x => x.Text = "test"); 
label1.TryInvoke(x => x.ForeColor = Color.Blue);

Or

this.TryInvoke(x =>
{
     label1.Text = "test";
     label1.ForeColor = Color.Blue;
});

Secondly, since you don't await anything at monitor_r, i'd recommend to use void instead of async Task.

Even if you're await something at monitor_r you don't need

await Task.Run(() => {
        monitor_r(label1);
    });

..because monitor_r itself is a task. So just call await monitor_r(label1);

Luthfi
  • 478
  • 1
  • 3
  • 16
0

If you wish to have a separate thread, you can try this using BackgroundWorker. You can implement the ReportProgress if you have a loop.

private void button1_Click(object sender, EventArgs e)
    {
        BackgroundWorker worker = new BackgroundWorker()
        {
            WorkerReportsProgress = true,
            WorkerSupportsCancellation = true
        };
        worker.RunWorkerCompleted += Worker_RunWorkerCompleted;
        worker.RunWorkerAsync();                
    }

    private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        MessageBox.Show(label1.Name);
        label1.ForeColor = Color.Blue;
        label1.Text = "test";
    }
Casperonian
  • 176
  • 5
  • 19
  • Please, let `BackgroundWorker` *rest in peace*: https://stackoverflow.com/questions/12414601/async-await-vs-backgroundworker – Dmitry Bychenko Nov 01 '18 at 11:59
  • **Since both work, it comes down to personal preference as to which you use when. What is quicker for you? What is easier for you to understand?** https://stackoverflow.com/questions/12414601/async-await-vs-backgroundworker – Casperonian Nov 01 '18 at 12:20
  • TPL (Task Process Library) has been designed in order to substitute `BackgroundWorker` and other obsolete solutions. Yes, `BackgroundWorker` works (in some simple cases); however, it brings problems (what if have to I start `BackgroundWorker` from `BackgroundWorker` in my routine version `5.1`?) https://blog.stephencleary.com/2013/05/taskrun-vs-backgroundworker-intro.html – Dmitry Bychenko Nov 01 '18 at 12:26
  • Thank you all for your help – Mike Nov 01 '18 at 12:26