C# 对windows窗体的线程安全调用正在冻结应用程序
我的应用程序中有一个异常处理项目,可以从任何地方调用该项目,以向用户显示系统存在问题。当调用按预期从UI中的某个位置发出时,一切都很好。当我从应用程序的任何UI部分调用时,一切都冻结了。我将代码包装在线程安全调用中,当逐步执行时,它们不需要调用。非常感谢您的帮助。代码如下: 表单内部C# 对windows窗体的线程安全调用正在冻结应用程序,c#,.net,visual-studio-2008,C#,.net,Visual Studio 2008,我的应用程序中有一个异常处理项目,可以从任何地方调用该项目,以向用户显示系统存在问题。当调用按预期从UI中的某个位置发出时,一切都很好。当我从应用程序的任何UI部分调用时,一切都冻结了。我将代码包装在线程安全调用中,当逐步执行时,它们不需要调用。非常感谢您的帮助。代码如下: 表单内部 void err_DispEvent(string text) { if (InvokeRequired) { Invoke(new Erro
void err_DispEvent(string text)
{
if (InvokeRequired)
{
Invoke(new Error.DisplayDelegate(err_DispEvent), new object [] {text});
}
else
{
this.Show();
}
}
来自班级的电话
public void FaultError(string errorMsg)
{
FaultForm fform = new FaultForm(errorMsg, "Internal Fault");
if (this.dispEvent != null)
{
dispEvent(errorMsg);
}
}
public event DisplayDelegate DispEvent
{
add { dispEvent += value; }
remove { dispEvent -= value; }
}
private event DisplayDelegate dispEvent;
public delegate void DisplayDelegate(string text);
在应用程序中如何使用该类的示例
ECDUExceptions.Error newError = ECDUExceptions.Error.getInstance();
newError.FaultError("Heater is not responding to function calls, it has been turned off");
使用BeginInvoke(…)而不是Invoke(…)。这将把您的消息请求放在队列的末尾使用BeginInvoke(…)而不是Invoke(…)。这将把您的消息请求放在队列的末尾为应该显示的消息创建某种类型的队列 从您需要的任何线程填充队列 从负责显示消息的GUI中,使用计时器退出队列并显示消息
简单化,但会毫不费力地工作。由于Forms.Timer在UI消息循环上运行,所以您不需要调用()任何东西。为应该显示的消息创建某种类型的队列 从您需要的任何线程填充队列 从负责显示消息的GUI中,使用计时器退出队列并显示消息
简单化,但会毫不费力地工作。由于Forms.Timer在UI消息循环上运行,所以您不需要调用()任何东西。重新调用方法时的一些信息:
BeginInvoke(…)
而不是Invoke(…)
,因为这不会等待调用完成,因此不会冻结调用线程操作
。因此,在您的情况下,您可以将调用更改为:
BeginInvoke(new Action<string>(err_DispEvent), text);
BeginInvoke(新操作(错误事件),文本);
重新调用方法时的一些信息:
BeginInvoke(…)
而不是Invoke(…)
,因为这不会等待调用完成,因此不会冻结调用线程操作
。因此,在您的情况下,您可以将调用更改为:
BeginInvoke(new Action<string>(err_DispEvent), text);
BeginInvoke(新操作(错误事件),文本);
如果签名匹配,则不是
BeginInvoke(err\u dispent,text)代码>足够吗?@codesparkle我相信是的,我写了完整的代码是为了更明确。你介意我建议对你的问题进行编辑(显示两个备选方案)吗?我已将代码切换到完整签名版本,但我仍然看到问题。InvokeRequired始终为false(这对我来说没有意义),因此我从不调用BeginInvoke命令InvokeRequired
beingfalse
表示您在到达该点时正在UI线程上运行。如果签名匹配,则不是BeginInvoke(err\u dispent,text)代码>足够吗?@codesparkle我相信是的,我写了完整的代码是为了更明确。你介意我建议对你的问题进行编辑(显示两个备选方案)吗?我已将代码切换到完整签名版本,但我仍然看到问题。InvokeRequired始终为false(这对我来说没有意义),因此我从不调用BeginInvoke命令InvokeRequired
beingfalse
表示您在到达该点时正在UI线程上运行。这样的队列已经存在:消息循环。使用BeginInvoke()在队列末尾添加操作。这样的队列已经存在:消息循环。使用BeginInvoke()在队列末尾添加操作。