gpt4 book ai didi

c# - Winforms Thread Application Hang(后台工作线程)

转载 作者:行者123 更新时间:2023-11-30 19:25:59 25 4
gpt4 key购买 nike

我已经使用 VS 2010 和 C# 构建了应用程序。

我在我的应用程序中使用 BackgroundWorker

当我单击按钮代码时,从数据库中获取记录并显示到 Datagrid 中。但问题是当我从代码运行它时它工作正常但是当我运行程序 .exe 时它被挂起。

//Declared delegate
delegate void SetControlPropertyThreadSafeDelegate(Control control, string propertyName, object propertyValue);

//Declared method to run control Thread safe
public static void SetControlPropertyThreadSafe(Control control, string propertyName, object propertyValue)
{
if (control.InvokeRequired)
{
control.Invoke(new SetControlPropertyThreadSafeDelegate(SetControlPropertyThreadSafe), new object[] { control, propertyName, propertyValue });
}
else
{
control.GetType().InvokeMember(propertyName, BindingFlags.SetProperty, null, control, new object[] { propertyValue });
}
}


//calling method like below
SetControlPropertyThreadSafe(dataGridView1, "DataSource", dtGrid2);

我不明白我哪里做错了。为什么程序挂起?

最佳答案

  void SetControlPropertyThreadSafe(...)

这样的方法有一个大问题。不幸的是很难根除,方式 SO 上推荐这个的帖子太多了。问题是它让程序员昏昏欲睡,它是“安全的”,所以它肯定不是问题的原因。将问题变成不可调试的问题。

绝对没有什么“安全”的:

  • 使用 Control.Invoke() 危险,很容易造成死锁。当 UI 线程中的代码执行某些不明智的操作(例如等待工作线程完成)时触发。仅当您背靠墙时才使用 Invoke(),实际上需要返回值。当您发现那是 必要时就不要这样做,除非您禁用 UI,否则它总是会竞争。始终改用 BeginInvoke()。

  • 它隐藏了一个消防水带问题。您会被哄骗去调用方法来更新每个控件,而不会考虑由此导致的问题。这正在用调用请求冲击 UI 线程。以比人眼所能看到的高约 50 倍的速度执行此操作,您将掩埋 UI 线程。它永远赶不上调用请求,一旦它分派(dispatch)了一个,就会有另一个等待执行。 UI 线程现在停止处理其正常职责,例如绘制窗口和处理用户输入。它看起来卡住,就像直接运行这段代码一样

  • 当用户关闭窗口但您的工作线程继续运行时,会发生非常不愉快的事情。调用一个不再存在的窗口。这通常会发出一声巨响,因此诊断起来并不难。有时它不会,无法调试,在停止线程和允许窗口关闭之间存在不可避免的线程竞争,只能通过不关闭窗口而是隐藏窗口来解决。

您的问题是第二颗子弹。它挂起是因为您的代码现在运行得更快了。 Invoke() 调用隐藏了调试器中的问题。完全摆脱这段代码,它危险,并从数据库查询中收集结果,比如说,一个 List<>。偶尔将它传递给 ReportProgress() 方法,这样您就不会处理 UI 线程。调用后重新创建列表,使其线程安全。

关于c# - Winforms Thread Application Hang(后台工作线程),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25783660/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com