【问题标题】:C# - When to Make Thread-Safe CallsC# - 何时进行线程安全调用
【发布时间】:2012-08-04 20:49:11
【问题描述】:

我有一个大型项目,我正在使用 C# 进行工作,C# 是一种我相当陌生的语言。该项目严重依赖 GUI,并且显示了大量数据。最近,我们在以前从未出现过的地方遇到了跨线程错误。这些错误发生的地方很容易解决:

if (logListView.InvokeRequired)
{
      logListView.BeginInvoke(new MethodInvoker(
          () => logListView.Items[logListView.Items.Count - 1].EnsureVisible()));
}
else
{
      logListView.Items[logListView.Items.Count - 1].EnsureVisible();
}

我的问题是:每次访问 Windows 窗体对象时都需要应用该方法?有特殊情况吗?我没有使用多线程,所以据我所知,这些错误发生在我的控制之外。例如。我无法控制哪段代码由哪个线程执行:C# 自己完成所有这些(我不太了解该语言)。为修改 GUI 的每一行实现一个 if 语句似乎非常令人讨厌。

【问题讨论】:

  • 您得到跨线程异常的事实意味着某些代码正在线程化。找出它是什么,你应该有控制权。

标签: c# winforms multithreading


【解决方案1】:

仅当您从 UI 线程外部(即从您生成的任何线程)访问 winform 组件时,您才需要该代码。核心库中有一些组件会产生线程,例如FileSystemWatcher。 Winforms 不只是自己产生线程,它只有 UI 线程。任何跨线程问题都是由您编写的代码或您使用的库引起的。

【讨论】:

  • 我自己不创建任何线程。有没有什么地方可以让我了解更多关于创建自己线程的类/组件的信息?
  • 没有关于它的纲要。您必须检查您的代码并确定产生线程的组件。让应用程序运行,当异常发生时,检查调用堆栈。检查您使用的任何 3rd 方库的文档。此外,使用ThreadPool 是线程。虽然您不是手动创建它们,但它正在产生线程。您是否偶然使用了它?
  • 我想这应该是显而易见的。我正在从 SerialPort 读取数据,并且几乎必须使用线程。我隔离了问题,一切都很好。
【解决方案2】:

您只需要在代码不在 GUI 线程中运行时调用代码。

我无法控制哪一段代码由哪个线程执行

是的,你可以。在 GUI 线程中运行哪些代码没有什么不可预测的,您只需要找出规则是什么。

在您的代码中用完 GUI 线程的唯一代码是作为异步回调运行的方法,例如计时器或异步 Web 请求。 (System.Windows.Forms.Timer 在 GUI 线程中运行 Tick 事件。)

(还有其他方法可以在另一个线程中运行代码,但是你会意识到使用多线程。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-01
    • 1970-01-01
    相关资源
    最近更新 更多