Visual C#,子线程停止父线程上的处理。为什么?
我正在通过VisualStudio2008Express使用Visual C#.Net,我正在从表单应用程序启动一个线程,以在循环中等待传入的数据。因此,每个循环等待数据可用,然后获取数据,然后再次开始等待 我在单独的线程中等待数据的主要原因是,我的表单仍然允许交互,而另一个表单则在那里等待数据 无论出于何种原因,我的窗体将在另一个线程等待时锁定 不幸的是,我被迫使用专有函数来获取数据。处理将在该函数处停止,直到它返回数据(等待硬件输入)。因此,用户可以徒劳地单击菜单选项而不产生任何效果,直到子线程返回数据,所有单击的菜单选项都将快速更改状态并再次锁定 所以,我的问题是:Visual C#,子线程停止父线程上的处理。为什么?,c#,multithreading,C#,Multithreading,我正在通过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组件的其他库。此函数的作用是等待缓冲区填充,然后从缓冲区中获取数据,然后告诉缓冲区再次开始填充。如果调用函数时缓冲区未满,它将等待。无法检查缓冲区状态。