Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.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# C“带a”的螺纹;请稍等;形式_C#_Multithreading_Forms - Fatal编程技术网

C# C“带a”的螺纹;请稍等;形式

C# C“带a”的螺纹;请稍等;形式,c#,multithreading,forms,C#,Multithreading,Forms,我有一个名为“等待”的表单,它在我的程序中显示和更新。它显示当前正在执行的任务和任务中正在完成的阶段。 我最近开始学习线程,并试图在我的程序中实现它们。然而,我似乎遇到了一个关于我的等待表的问题。我可以将表单传递到线程中,线程中的任务将在开始时使用Wait.Show(),更新Wait-for的内容,并在结束时使用Wait.Hide()。(我不会在每个任务完成后使用Wait.Close(),因此我不必为每个任务创建等待表单的新实例。) 我的问题是这个。我的测试运行将成功地将等待表单传递到线程中,在

我有一个名为“等待”的表单,它在我的程序中显示和更新。它显示当前正在执行的任务和任务中正在完成的阶段。 我最近开始学习线程,并试图在我的程序中实现它们。然而,我似乎遇到了一个关于我的等待表的问题。我可以将表单传递到线程中,线程中的任务将在开始时使用
Wait.Show()
,更新Wait-for的内容,并在结束时使用
Wait.Hide()
。(我不会在每个任务完成后使用
Wait.Close()
,因此我不必为每个任务创建等待表单的新实例。)

我的问题是这个。我的测试运行将成功地将等待表单传递到线程中,在需要时更新它,并在完成时隐藏它。然而,当我点击我的退出按钮时,我不能取消(?)等待表单,因为我收到了以下错误

跨线程操作无效:从服务器访问控件“Frm\U Wait” 线程,而不是创建它的线程

我为测试运行准备的代码如下:

    Excel.Application ObjApp = new Excel.Application();
    Specialised Modules = new Specialised();
    ErrorHandling EH = new ErrorHandling();
    Frm_Wait Wait = new Frm_Wait();

    private void BtnTest_Click(object sender, EventArgs e)
    {
        try
        {
            Thread RCCThread = new Thread(() => UpdateRCCountsThread(Wait));
            RCCThread.Start();
        }
        catch (Exception Ex)
        {
            MessageBox.Show(Ex.Message);
        }
    }


    public void UpdateRCCountsThread(Frm_Wait Wait)
    {
        try
        {
            string RCCountsSource = ResourceDetails.MainResources(this, EH, "RCCounts");
            Wait.Show();

            bool check = Modules.UpdateRCCounts(this, ObjApp, EH, Wait);
            if (check == true)
            {
                //Record completed task to LogFile.
                Thread MsgTaskComplete = new Thread(() => MsgUpdateThread(this, ObjApp, EH, 1, 10, Path.GetDirectoryName(RCCountsSource), Path.GetFileName(RCCountsSource), "", 0, 0, 0, 0, "RC Counts File updated.", "Y"));
                MsgTaskComplete.Start();
            }
            else
            {
                MessageBox.Show("An Error occurred, Please Check LogFile.");
            }
            Wait.Hide();
        }
        catch (Exception URC)
        {
            Thread MsgTaskCatch = new Thread(() => MsgUpdateThread(this, ObjApp, EH, 4, 1, "", "", "", 0, 0, 0, 0, "BtnTest_Click Clicked - Error Occurred. System says: " + URC.Message, "N"));
            MsgTaskCatch.Start();
            MessageBox.Show("An Error Occurred" + Environment.NewLine + URC.Message);
        }
    }
我的退出按钮抛出错误的代码部分如下:

            if (Wait != null)
            {
                Wait.Close();
                Wait = null;  //this is the line that causes the error.
            }
有人知道我哪里出错了吗? 我是否必须为每个线程创建一个等待表单的新实例,或者是否可以传递它,然后将控制权/所有权返回给主类


谢谢

您无法从创建对象的另一个线程访问该对象。您在UI线程中创建了表单,并且希望从新创建的线程访问它。使用控件的/来调用Dispatcher/UI-Thread中的方法。据我所知,(记住,我刚刚开始使用Threads)invoke将用于编辑等待表单的内容。这部分工作正常,更新正常。但是,我添加了一个If invokererequired方法来处理wait表单上文本的更新。我的问题是何时/如何在线程之间“显示”和“隐藏”窗体。如果我在创建线程之前将Show in添加到按钮click中,并且在线程启动之后将Hide添加到按钮click中,那么表单只会显示不到一秒钟,但是线程将继续运行。对于msdn文档中的第一条语句:invoke:在拥有“myFormControl1”控件的底层窗口句柄的线程上执行指定的委托。你的第二句话:据我所知,线程就是这样做的。如果您必须等待线程的完成,那么线程将是无用的。我想这就是为什么你的窗户会在一秒钟后隐藏起来。您的
updatercountsthread()
-方法在另一个线程中运行,这意味着即使您访问的表单不在第二个嵌套线程中,也会出现此异常。因此,对于我的程序,我将等待每个任务完成,然后再允许用户执行任何其他操作。这是否意味着线程在我的工作范围内毫无意义?也就是说,只有当你需要一次做多件事,或者在线程化任务在后台运行时继续使用其他程序功能时,它们才有用?如果你的用户必须等待,你至少应该使用BackgroundWorker之类的工具,因为你不想在执行长时间操作时阻塞UI。否则,您将在UI线程中执行所有操作,这将导致阻塞UI。线程对于异步或并行工作流很有用。您不能从创建对象的另一个线程访问该对象。您在UI线程中创建了表单,并且希望从新创建的线程访问它。使用控件的/来调用Dispatcher/UI-Thread中的方法。据我所知,(记住,我刚刚开始使用Threads)invoke将用于编辑等待表单的内容。这部分工作正常,更新正常。但是,我添加了一个If invokererequired方法来处理wait表单上文本的更新。我的问题是何时/如何在线程之间“显示”和“隐藏”窗体。如果我在创建线程之前将Show in添加到按钮click中,并且在线程启动之后将Hide添加到按钮click中,那么表单只会显示不到一秒钟,但是线程将继续运行。对于msdn文档中的第一条语句:invoke:在拥有“myFormControl1”控件的底层窗口句柄的线程上执行指定的委托。你的第二句话:据我所知,线程就是这样做的。如果您必须等待线程的完成,那么线程将是无用的。我想这就是为什么你的窗户会在一秒钟后隐藏起来。您的
updatercountsthread()
-方法在另一个线程中运行,这意味着即使您访问的表单不在第二个嵌套线程中,也会出现此异常。因此,对于我的程序,我将等待每个任务完成,然后再允许用户执行任何其他操作。这是否意味着线程在我的工作范围内毫无意义?也就是说,只有当你需要一次做多件事,或者在线程化任务在后台运行时继续使用其他程序功能时,它们才有用?如果你的用户必须等待,你至少应该使用BackgroundWorker之类的工具,因为你不想在执行长时间操作时阻塞UI。否则,您将在UI线程中执行所有操作,这将导致阻塞UI。线程对于异步或并行工作流很有用。