Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 对windows窗体的线程安全调用正在冻结应用程序_C#_.net_Visual Studio 2008 - Fatal编程技术网

C# 对windows窗体的线程安全调用正在冻结应用程序

C# 对windows窗体的线程安全调用正在冻结应用程序,c#,.net,visual-studio-2008,C#,.net,Visual Studio 2008,我的应用程序中有一个异常处理项目,可以从任何地方调用该项目,以向用户显示系统存在问题。当调用按预期从UI中的某个位置发出时,一切都很好。当我从应用程序的任何UI部分调用时,一切都冻结了。我将代码包装在线程安全调用中,当逐步执行时,它们不需要调用。非常感谢您的帮助。代码如下: 表单内部 void err_DispEvent(string text) { if (InvokeRequired) { Invoke(new Erro

我的应用程序中有一个异常处理项目,可以从任何地方调用该项目,以向用户显示系统存在问题。当调用按预期从UI中的某个位置发出时,一切都很好。当我从应用程序的任何UI部分调用时,一切都冻结了。我将代码包装在线程安全调用中,当逐步执行时,它们不需要调用。非常感谢您的帮助。代码如下:

表单内部

    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
    being
    false
    表示您在到达该点时正在UI线程上运行。如果签名匹配,则不是
    BeginInvoke(err\u dispent,text)足够吗?@codesparkle我相信是的,我写了完整的代码是为了更明确。你介意我建议对你的问题进行编辑(显示两个备选方案)吗?我已将代码切换到完整签名版本,但我仍然看到问题。InvokeRequired始终为false(这对我来说没有意义),因此我从不调用BeginInvoke命令
    InvokeRequired
    being
    false
    表示您在到达该点时正在UI线程上运行。这样的队列已经存在:消息循环。使用BeginInvoke()在队列末尾添加操作。这样的队列已经存在:消息循环。使用BeginInvoke()在队列末尾添加操作。