Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.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
Visual C#,子线程停止父线程上的处理。为什么?_C#_Multithreading - Fatal编程技术网

Visual C#,子线程停止父线程上的处理。为什么?

Visual C#,子线程停止父线程上的处理。为什么?,c#,multithreading,C#,Multithreading,我正在通过VisualStudio2008Express使用Visual C#.Net,我正在从表单应用程序启动一个线程,以在循环中等待传入的数据。因此,每个循环等待数据可用,然后获取数据,然后再次开始等待 我在单独的线程中等待数据的主要原因是,我的表单仍然允许交互,而另一个表单则在那里等待数据 无论出于何种原因,我的窗体将在另一个线程等待时锁定 不幸的是,我被迫使用专有函数来获取数据。处理将在该函数处停止,直到它返回数据(等待硬件输入)。因此,用户可以徒劳地单击菜单选项而不产生任何效果,直到子

我正在通过VisualStudio2008Express使用Visual C#.Net,我正在从表单应用程序启动一个线程,以在循环中等待传入的数据。因此,每个循环等待数据可用,然后获取数据,然后再次开始等待

我在单独的线程中等待数据的主要原因是,我的表单仍然允许交互,而另一个表单则在那里等待数据

无论出于何种原因,我的窗体将在另一个线程等待时锁定

不幸的是,我被迫使用专有函数来获取数据。处理将在该函数处停止,直到它返回数据(等待硬件输入)。因此,用户可以徒劳地单击菜单选项而不产生任何效果,直到子线程返回数据,所有单击的菜单选项都将快速更改状态并再次锁定

所以,我的问题是:
为什么我的孩子会挂起我的表格?难道我们不应该是独立的吗? 如果子线程正在等待某些内容,我可以做些什么来强制窗体继续运行

我目前正在制作这样的线程:

ControlThread = new Thread(new ThreadStart(Run));
ControlThread.Start();
public void Run()
{
    while (!StopEventHandle.WaitOne(0, true))
    {
        int data = WaitForData();
        invoke(DelegatedResults);
    }
}
其中,我的Run函数如下所示:

ControlThread = new Thread(new ThreadStart(Run));
ControlThread.Start();
public void Run()
{
    while (!StopEventHandle.WaitOne(0, true))
    {
        int data = WaitForData();
        invoke(DelegatedResults);
    }
}

其中DelegatedResults是我表单上的一个函数,它使用传入的数据更新一些文本框。

您应该至少在1之前休眠该线程

简答覆:

this.Invoke((ThreadStart)delegate()
{
    textBox1.Text = "Yahoo";
});
长答覆:

using System.Threading;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        Thread thread;
        bool finishingThread, finished;

        public Form1()
        {
            InitializeComponent();
            finishingThread = false;
            finished = false;
            thread = new Thread(Run);
            thread.Start();
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            finishingThread = true;
            if(!finished) e.Cancel = true;
            base.OnClosing(e);
        }

        private void Run()
        {
            while(!this.Visible);
            while(this.Visible && !finishingThread)
            {
                this.Invoke((ThreadStart)delegate()
                {
                    textBox1.Text = "Yahoo";
                });
                Thread.Sleep(100);
            }
            finished = true;
            this.Invoke((ThreadStart)delegate()
            {
                this.Close();
            });
        }
    }
}
我被迫使用专有功能来获取数据

关于这个函数你没说太多。您的问题表明它是作为COM服务器实现的,这很常见。COM负责COM服务器的线程要求。这样的服务器在注册表中用ThreadingModel注册表项指示它支持什么类型的线程。一个非常常见的设置是“公寓”,这也是缺少钥匙时的默认设置

该设置表示服务器不支持线程。它需要一个单线程单元(STA)。COM会处理这个问题,它会自动将服务器上的任何调用封送到STA线程。你的UI线程。因此,在通话结束前,它会像门钉一样死掉


图书馆的文档中应该有关于这方面的内容。联系供应商寻求支持也是个好主意。如果您无法获得帮助,那么您可以尝试的第一件事是在工作线程而不是UI线程上初始化服务器。如果ThreadModel是“两者”,那么这将解决问题。如果这没有帮助,那么您需要创建自己的STA线程。调用Thread.SetApartmentState()在启动线程之前,使用线程中的Application.Run()启动您自己的消息循环。您可能可以跳过循环,但这通常是必需的。

您可以尝试使用BackgroundWorker类,以避免执行更复杂的线程管理。BackgroundWorker类虽然看起来比我管理线程所做的简单得多,如果我的子线程正在等待,仍然不允许我的主线程继续。我的运行线程确实在某个地方有睡眠,而且它不仅仅是等待一个函数返回。从本质上说,主窗体确实会更新,但只有当它通过函数时才会更新。我用来获取数据的函数很可能是以最不方便的方式设置的,文档非常有限,并且来自其他大陆。话虽如此,我可能需要听从STA的建议。我是一个线程新手。你说的“启动你自己的消息循环”是什么意思?链接:我正在使用的函数中的一些附加信息:它来自一个dotNet库,但它访问可能有或可能没有COM组件的其他库。此函数的作用是等待缓冲区填充,然后从缓冲区中获取数据,然后告诉缓冲区再次开始填充。如果调用函数时缓冲区未满,它将等待。无法检查缓冲区状态。