Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/311.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#无法访问-a-disposed-object-工作线程访问的表单_C#_Multithreading - Fatal编程技术网

c#无法访问-a-disposed-object-工作线程访问的表单

c#无法访问-a-disposed-object-工作线程访问的表单,c#,multithreading,C#,Multithreading,我是一个比较新的c#用户,所以如果我犯了一些新手错误,请原谅我。我已搜索此错误的解决方法,但找不到适合我的实现 我有一个工作线程,它基本上是循环的,而booleanisCalibrationActive是真的。在工作线程期间,我设置了一个回调来访问主线程中的标签,并根据工作线程更改文本。在主线程中的formclosing事件上,我将isCalibrationActive设置为false,从理论上讲,这将停止工作线程中的循环。一旦我关闭表单,就会出现错误 表单关闭事件代码: private voi

我是一个比较新的c#用户,所以如果我犯了一些新手错误,请原谅我。我已搜索此错误的解决方法,但找不到适合我的实现

我有一个工作线程,它基本上是循环的,而boolean
isCalibrationActive
是真的。在工作线程期间,我设置了一个回调来访问主线程中的标签,并根据工作线程更改文本。在主线程中的formclosing事件上,我将
isCalibrationActive
设置为false,从理论上讲,这将停止工作线程中的循环。一旦我关闭表单,就会出现错误

表单关闭事件代码:

private void Form2_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (e.CloseReason == CloseReason.UserClosing)
        {
            DialogResult result = MessageBox.Show("The Calibration stage is not yet complete. Are you sure you want to exit?", "Dialog Title", MessageBoxButtons.YesNo);
            if (result == DialogResult.Yes)
            {
                isCalibrationActive = false;
                Thread.Sleep(10000);
                return;
            }
            else
            {
                e.Cancel = true;
            }
        }
        else
        {
            e.Cancel = true;
        }
    }
工作线程:编辑:很抱歉,我之前把测试代码留在了那里。

    private void refreshXY()
    {
        var currentpath = new StringBuilder(255);

        //store current directory and set to dll directory.
        UnsafeNativeMethods.GetDllDirectory(currentpath.Length, currentpath);
        UnsafeNativeMethods.SetDllDirectory( "D:\\UI_still_in_progress\\Debug" );
        UnsafeNativeMethods.LoadLibrary("dllTESTER.dll");

        while (isCalibrationActive)
        {                
            xx = UnsafeNativeMethods.grabx();
            yy = UnsafeNativeMethods.graby();
            if (xx == 0) { xx = 0.001;}
            if (yy == 0) { yy = 0.001;}
            SetXlab(xx.ToString());
            SetYlab(yy.ToString());
        }
        //restore old directory
        UnsafeNativeMethods.SetDllDirectory(currentpath.ToString());
    }
错误发生在基本相同的
SetXlab
SetYlab
功能期间。另外,我将它放在另一个线程中的原因是,它正在从另一个应用程序读取实时数据,需要不断更新。如下所示:

private void SetYlab(string yval)
    {
        // InvokeRequired required compares the thread ID of the
        // calling thread to the thread ID of the creating thread.
        // If these threads are different, it returns true.
        if (this.yshow.InvokeRequired)
        {
            SetTextCallback yD = new SetTextCallback(SetYlab);
            if (isCalibrationActive) { this.Invoke(yD, new object[] { yval }); }
        }
        else
        {
            this.yshow.Text = yval;
        }
    }

具体来说,行
this.Invoke(yD,newobject[]{yval});}是导致错误的原因。有什么办法可以避免这种情况吗?

我可能会使用一个名为
calGuiUpdateTimer
System.Windows.Forms(SWF)计时器,带有
Tick
类似的功能

        xx = 0;
        yy = 100;
        xx = UnsafeNativeMethods.grabx();
        yy = UnsafeNativeMethods.graby();
        if (xx == 0) { xx = 0.001;}
        if (yy == 0) { yy = 0.001;}
        this.xshow.Text = xx.ToString();
        this.yshow.Text = yy.ToString();
然后去掉
isCalibrationActive
,改为
calGuiUpdateTimer.Enabled

SWF定时器总是在GUI线程上运行,这样您就不必担心切换线程;您可以完全摆脱所有那些
调用所需的
垃圾函数。让你的东西更容易


也就是说,如果
grabx
graby
是可能运行缓慢的函数,那么此选项将使您的GUI结巴,并且SWF计时器是不可接受的。在这种情况下,请继续使用后台线程解决方案,并参阅以获得指导(同时请参阅以简化回调)。

我可能会使用名为
calGuiUpdateTimer
System.Windows.Forms(SWF)计时器,并使用类似的
Tick
函数

        xx = 0;
        yy = 100;
        xx = UnsafeNativeMethods.grabx();
        yy = UnsafeNativeMethods.graby();
        if (xx == 0) { xx = 0.001;}
        if (yy == 0) { yy = 0.001;}
        this.xshow.Text = xx.ToString();
        this.yshow.Text = yy.ToString();
然后去掉
isCalibrationActive
,改为
calGuiUpdateTimer.Enabled

SWF定时器总是在GUI线程上运行,这样您就不必担心切换线程;您可以完全摆脱所有那些
调用所需的
垃圾函数。让你的东西更容易


也就是说,如果
grabx
graby
是可能运行缓慢的函数,那么此选项将使您的GUI结巴,并且SWF计时器是不可接受的。在这种情况下,请继续使用后台线程解决方案,并参阅以获取指导(同时请参阅以简化回调)。

grabx
和graby
运行方法是否合理快速?比如通常小于5毫秒,很少超过50毫秒,而且从不超过一秒钟?(新手犯的错误--C#“事实上”的编码标准使用PascalCase作为方法和属性,仅供参考;随意做你想做的事)是
grabx
graby
运行速度相当快的方法吗?比如一般少于5毫秒,很少超过50毫秒,而且从不超过一秒钟?(新手犯的错误--C#“事实上”的编码标准使用PascalCase作为方法和属性,仅供参考;随意做你想做的事)谢谢,我意识到我可以让worker线程更新全局变量,还有timer.tick事件更新表单:)谢谢,我意识到我可以让工作线程更新全局变量,而timer.tick事件更新表单:)