【问题标题】:Invoke lot of methods on UI thread from bakcground threads从后台线程调用 UI 线程上的许多方法
【发布时间】:2018-10-16 10:42:59
【问题描述】:

关于我的问题的一些信息:

我有一个 Windows 窗体应用程序,它有一个多线程,可以长时间并行计算。在计算这些线程修改 UI 元素(例如标签、文本框、按钮等)并写入 RichTextBox 时。 我有很多线程安全调用的委托,并多次检查 InvokeRequired。

我有很多这样的方法:

private void AppendText(string text)
{
    if(richTextBox.InvokeRequired)
    {
        Invoke(myDelegate, new object[] { text });
    }
    else
    {
        richTextBox.Append(text);
    }
}

我的问题是:

这是从后台线程修改 UI 线程控件的好方法,还是我犯了一些架构错误?

【问题讨论】:

  • 是的Async-Await 是最好和更简洁的方法,同时处理在后台进行,Ui 会在 Ui 线程上自动更新,无需复杂的代码

标签: c# multithreading thread-safety


【解决方案1】:

下面是一个简单的代码来解释Async-Await的用法

public async Task Main()
{
    var result = await Background("Test");
    // Update Ui here, its on Ui thread
}

// Executed Asynchronously in the Background
public async Task<string> Background(string text)
{
    return await Task.FromResult(text);
}
  • Background方法是异步处理的,如果是通过网络像db调用,那么不需要线程池线程,如果在内存中,会使用线程池线程
  • 一旦Background方法,结果可以在控件上更新,其自动UI线程
  • 您甚至可以显式使用Task Parallel Library 来处理数据,然后更新结果
  • await 仍然是一个阻塞调用,虽然它会释放调用上下文,这意味着 Ui 不会冻结,它仍然可以访问,但是可以使用 Task.Run 进行非阻塞调用,返回时可以用于更新 Ui,但您始终必须阻止 Main / Ui 线程退出

编辑 1(异步按钮点击事件)

public async void Button1_Click(object sender,EventArgs e)
{
   await (Async Method Call)
   // Update Ui
}

【讨论】:

  • 我有一个按钮点击事件,我称之为我的线程正在工作。我怎么能在那里使用 async-await?
  • 所有事件默认可以异步,按照我上面使用的模式,你只需要标记async,返回一个void,最好只用于事件并使用@ 987654331@里面用于进行异步调用
  • 检查Edit 1 (Async Button Click Event)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-05
  • 2011-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-24
  • 2012-12-15
相关资源
最近更新 更多