简体   繁体   English

我对线程的错误是什么?

[英]What am I doing wrong with Threading?

Synopsis: 概要:

I am trying to convert a non threaded application to a threaded application. 我试图将非线程应用程序转换为线程应用程序。 I have not used threads in an application in about 10 years and am very rusty with the concept. 我在大约10年的时间里没有在应用程序中使用过线程,而且这个概念非常生疏。 There is just something I am not grasping. 我只是抓不到的东西。 Can you please look at my (very short) before and after code to see what I am doing wrong and why it is wrong? 你可以在代码前后查看我的(非常简短的),看看我做错了什么以及为什么这是错的? All help is greatly appreciated! 非常感谢所有帮助! Thanks! 谢谢!

Errors seen: 看到的错误:

My code is not responding. 我的代码没有响应。 I can run and execute the buttons to launch the applications but rather than start a new thread and just work, they freeze and show a "not responding" message. 我可以运行并执行按钮来启动应用程序,但不是启动新线程而只是工作,它们会冻结并显示“无响应”消息。 I am not sure what i did wrong. 我不确定我做错了什么。 Did i just implement the threads incorrectly? 我是不是错误地实现了线程?

Non threaded code: 非线程代码:

//this opens the user input windows form
private void UserInputButton_Click(object sender, EventArgs e)
{
    enumerationStation EnumerationForm = new enumerationStation();
    EnumerationForm.Show();
    //userform UserForm = new userform();
    //UserForm.Show();
}

//this opens the correlationApplication windows form
private void CorrelationApplication_Click(object sender, EventArgs e)
{
    CorrelationApplication CorrelationApplicationForm = new CorrelationApplication();
    CorrelationApplicationForm.Show();
}

Broken threaded code: 断线代码:

//this opens the user input windows form
private void UserInputButton_Click(object sender, EventArgs e)
{
    BackgroundWorker bg = new BackgroundWorker();
    bg.DoWork += new DoWorkEventHandler(enumerationStuff);
    bg.RunWorkerAsync();

}
//run enumeration application in new thread
private void enumerationStuff(object sender, DoWorkEventArgs e)
{
    enumerationStation EnumerationForm = new enumerationStation();
    EnumerationForm.Show();
}

//this opens the correlationApplication windows form
private void CorrelationApplication_Click(object sender, EventArgs e)
{
    BackgroundWorker bg = new BackgroundWorker();
    bg.DoWork += new DoWorkEventHandler(correlationStuff);
    bg.RunWorkerAsync();
}
//run correlation application in new thread
private void correlationStuff(object sender, DoWorkEventArgs e)
{
    CorrelationApplication CorrelationApplicationForm = new CorrelationApplication();
    CorrelationApplicationForm.Show();
}

BackgroundWorkers are designed for doing just that - working in the background. BackgroundWorkers专为此而设计 - 在后台工作。 They aren't designed to display new windows or present any UI themselves - that by definition is foreground work. 它们不是为了显示新窗口或自己呈现任何UI而设计的 - 根据定义它们是前台工作。 BackgroundWorkers don't handle any messages, so they won't respond to mouseclicks, keyboard input, or anything at all, which is why the windows just display "Not Responding". BackgroundWorkers不处理任何消息,因此它们不会响应鼠标点击,键盘输入或任何内容,这就是窗口只显示“无响应”的原因。

It's difficult to answer this question since I'm not really clear on what you're actually trying to achieve here. 很难回答这个问题,因为我并不清楚你在这里想要达到的目标。 What's wrong with your first, non-threaded code? 你的第一个非线程代码出了什么问题?

If the "individual applications" (which are really just forms) are freezing the entire application, they're probably doing an awful lot of work in the UI thread. 如果“个别应用程序”(实际上只是表单)冻结整个应用程序,他们可能在UI线程中做了大量的工作。 In that case, BackgroundWorkers could be a solution, but you're using them in the wrong place. 在这种情况下,BackgroundWorkers可能是一个解决方案,但你在错误的地方使用它们。 Find the code that's doing "lots of work" (whatever work that is), and see if you can put that code (and only that code) into a BackgroundWorker. 找到正在做“大量工作”的代码(无论是什么工作),看看你是否可以将该代码(只有那些代码)放入BackgroundWorker中。 What you can't do, though, is do anything with the UI from inside a BackgroundWorker - you only have one UI thread (the one you start in), and only that thread can touch the UI. 但是,你不能做的是在BackgroundWorker中对UI做任何事情 - 你只有一个UI线程(你开始的那个),只有那个线程可以触摸UI。

The .NET/Windows user interface does not allow performing any UI operation from anything from the single user interface thread. .NET / Windows用户界面不允许从单个用户界面线程执行任何 UI操作。 In a nutshell, the UI itself is single threaded, while any long running operations that don't touch the UI can happily occur in a secondary/background thread. 简而言之,UI本身是单线程的,而任何不接触UI的长时间运行操作都可以在辅助/后台线程中愉快地进行。

This is why things like Control.Invoke exist, to allow you to request a particular piece of code be executed in the UI thread context. 这就是存在Control.Invoke类的原因,允许您在UI线程上下文中请求执行特定代码。

The main issue here is your trying to create & run GUI components on a background thread. 这里的主要问题是您尝试在后台线程上创建和运行GUI组件。 Given you need to prompt the user for input I don't see why you would want to spawn this code off into separate threads. 鉴于您需要提示用户输入,我不明白为什么您希望将此代码生成到单独的线程中。

Keep your form launching in the UI thread and then pass any extra work those forms do into a background thread instead. 保持表单在UI线程中启动,然后将这些表单所做的任何额外工作传递到后台线程中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM