Updating UI from events using asyc await

前端 未结 4 1463
北海茫月
北海茫月 2020-12-31 00:16

I am trying to understand how to update a UI from an event while using async/await pattern. Below is the test code I am using on a WinForm app. I am not even sure this is th

相关标签:
4条回答
  • 2020-12-31 00:49

    Here is another example

    async void DoExport()
    {
        var rMsg = "";
        var t = await Task<bool>.Factory.StartNew(() => ExportAsMonthReport(LastMonth.Name, LastYear.Name, out rMsg));
    
        if (t)
        {
              BeginInvoke((Action)(() =>
              {
                   spinnerMain.Visible = false;
                   menuItemMonth.Enabled = true;
    
                   MetroMessageBox.Show(this, rMsg, "Export", MessageBoxButtons.OK, MessageBoxIcon.Information, 200);
              }));
       }
       else
       {
              BeginInvoke((Action)(() =>
              {
                   spinnerMain.Visible = false;
                   menuItemMonth.Enabled = true;
    
                   MetroMessageBox.Show(this, rMsg, "Export", MessageBoxButtons.OK, MessageBoxIcon.Error, 200);
              }));
        }
    }
    
    0 讨论(0)
  • 2020-12-31 00:51

    You should use Invoke method of Control. It executes some code in Control's thread. Also you can check InvokeRequired property to check if you need to call Invoke method (it checks if the caller is on a different thread than the one the control was created on).

    Simple example:

    void SomeAsyncMethod()
    {
        // Do some work             
    
        if (this.InvokeRequired)
        {
            this.Invoke((MethodInvoker)(() =>
                {
                    DoUpdateUI();
    
                }
            ));
        }
        else
        {
            DoUpdateUI();
        }
    }
    
    void DoUpdateUI()
    {
        // Your UI update code here
    }
    

    In some cases you should check the IsHandleCreated property of Control before calling Invoke method. If IsHandleCreated returns false then you need wait while Control's handle will be created

    0 讨论(0)
  • 2020-12-31 00:54

    The async pattern has support for progress updates.

    In short, your async method can take an IProgress<T>, and your calling code passes in an implementation of that interface (usually Progress<T>).

    public class ProcessWithUpdates
    {
      public async Task Run(IProgress<string> progress)
      {
        await Task.Run(() =>
        {
          for (int i = 0; i < 10; i++)
          {
            if (progress != null)
              progress.Report(String.Format("Update {0}", i));
            Thread.Sleep(500);
          }
        });
      }
    }
    
    // calling code
    ProcessWithUpdates pwp = new ProcessWithUpdates();
    await pwp.Run(new Progress<string>(pwp_StatusUpdate));
    
    0 讨论(0)
  • 2020-12-31 00:57

    //Just declare a delegate like so

    delegate void Add(string msg);
    

    //Then declare the delegate method like so:

    var add = new Add((msg) => {
       _listBox_Output.Items.Add(msg);
    });
    

    //Now just call the delegate:

    void pwe_StatusUpdate(string updateMsg)
        {
    
          _listBox_Output.Invoke(add,updateMsg);
        }
    
    0 讨论(0)
提交回复
热议问题