winforms中的异步UI更新

本文关键字:UI 更新 异步 winforms | 更新日期: 2023-09-27 17:59:17

我想在windows窗体中的文本框中实现与visualstudio中的输出窗口中类似的效果——这意味着当它打印一些东西时,你实际上可以自由地上下滚动。

不幸的是,我使用async/await的尝试仍然没有成功(我正在阻塞UI)。

到目前为止,我得到了这个:

private async void button1_Click(object sender, EventArgs e)
    {
        try
        {
            richTextBox1.Text = "";
            if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                await ProcessFile(openFileDialog1.FileNames.First());
            }
        }
        catch (Exception gg)
        {
            SupportingClass.SaveError(gg);
        }
    }
//simplified
private async Task ProcessFilecsv(string path)
{
     IEnumerable<T> products = GetProducts<T>(path);
     foreach (var item in products)
     {
         string select = @"select something from datatable";
         List<object[]> result = await  Support.Overall.RetrieveSelectDataAsync(select);
         richTextBox1.AppendText(int.Parse(result[0][0].ToString()) > 0 ? "Added" : "Not found"));
     }
}

我也尝试过使用Task.Factory.StartNew(()=> dosth().ContinureWith(x => /* appending to richboxtext1 */ ),但也没有成功。

我错过了什么?

winforms中的异步UI更新

我认为应该这样做:

private async void button1_Click(object sender, EventArgs e)
{
    ...
    await ProcessFile(openFileDialog1.FileNames.First());
    ...
}
private async Task ProcessFile(string path) 
{
    return Task.StartNew(() => { 
        IEnumerable<T> products = GetProducts<T>(path);
        foreach (var item in products)
        {
            string select = @"select something from datatable";
            List<object[]> result = await  Support.Overall.RetrieveSelectDataAsync(select);
            // i'm using a little helper method here...
            Do(richTextBox1, rb => rb.AppendText(int.Parse...);
        }
    });
}
public static void Do<TControl>(TControl control, Action<TControl> action) where TControl : Control
{
    if (control.InvokeRequired)
    {
        control.Invoke(action, control);
    }
    else
    {
        action(control);
    }
}