C#:阻止主线程运行 [英] C#: Stop a main thread from running
问题描述
如何停止应用程序上运行的主线程?我有三个类:第一个类是主窗体,第二个类是其中带有图像的按钮的用户控件,最后一个线程是包含不断更改按钮图标的代码的类.在usercontrol类中.
因此,只要打开主窗口,线程就会继续调用usercontrol类,而包含主线程"的usercontrol类将调用第三个类.
问题是当我关闭主窗体时,我注意到我的主线程仍在运行.关闭主窗体时如何关闭主线程?
示例代码:
How can I stop the main thread that is running on my application? I have three classes: the first class is in the main form, the second is a user control that has a button in it with an image, and the last thread is the class that contains a code that keeps on changing the icon of the button in the class usercontrol.
So as long as the main window is open, the thread just keeps on invoking the class usercontrol and the usercontrol class that contains the "main thread" calls the third Class.
The problem is when I close my main form, I notice that my main thread is still running. How can I close the main thread when I close my main form?
Sample code:
/* This is the Main form that is being displayed and it contains a flowlayout */
public Main(){
InitializeComponent();
/* a flowlayoutpanel attached at the main form */
flowLayoutPanel1.AutoScroll = true;
flowLayoutPanel1.Dock = DockStyle.Fill;
for (int i = 0; i < 10; i++)
{
//flowLayoutPanel1.Controls.Add(createButton((i+1) + ""));
flowLayoutPanel1.Controls.Add(new Monitor());
}
}
/*End of main form */
/* This is my 2nd class which is a usercontrol class */
public partial class Monitor : UserControl
{
check chk = new check();
public static Thread thread;
public Monitor()
{
InitializeComponent();
thread = new Thread(chk.changecolor);
chk.getButton = this.button1;
thread.Start();
}
private void button1_Click(object sender, EventArgs e)
{
chk.isChange = true;
}
}
/* This is the 3rd class that handles the changing of the button icons in the 2nd class (the usercontrol class) */
class check
{
bool t = false;
bool change = false;
Button b;
public void changecolor() {
// btn.Image = global::Practice.Properties.Resources.Untitled_1;
while(true){
Console.WriteLine("ahha");
if (t)
{
if (change)
{
b.Image = global::CafeMonitorSystem.Properties.Resources.logon;
change = false;
}
else
{
b.Image = global::CafeMonitorSystem.Properties.Resources.Untitled_1;
change = true;
}
}
Thread.Sleep(300);
}
}
public bool isChange {
get{ return t;}
set{
t= value;
change = value;
}
}
public Button getButton {
get {return b;}
set {b = value;}
}
}
因此,问题在于包含主线程"的UserControl类.即使关闭主窗体,它也可以继续运行.
关闭表单时如何终止它?
我们非常感谢您的帮助.
So the problem is the UserControl class that contains the "Main Thread". It keeps on running even when the main form is closed.
How can I terminate it when I close the form?
Any help is greatly appreciated.
推荐答案
您的辅助线程仍在运行,并且只有这些线程完成了所需的操作后,主线程才会退出.
因为您有无限循环while (true)...
,该线程将永远不会退出,因此您需要将其停止.
这是一些阻止它的代码.
Your secondary threads are still running and the main thread will only exit once these thread(s) have finished what they needed to do.
Because you have infinite loopwhile (true)...
that thread will never exit so you will need to stop it.
Here is some code to stop it.
public partial class Monitor : UserControl
{
check chk = new check();
public static Thread thread;
public Monitor()
{
InitializeComponent();
thread = new Thread(chk.changecolor);
chk.getButton = this.button1;
thread.Start();
}
private void button1_Click(object sender, EventArgs e)
{
chk.isChange = true;
}
//HERE IS THE STOP CODE
public void StopThread()
{
//this will let the thread exit gracefully
chk._CanRun = false;
}
}
另外,您需要更改无限循环
试试这样的东西
Also, you need to change your infinite loop
try something like this
class check
{
bool t = false;
bool change = false;
public bool _CanRun = true;//HERE ADDED THIS
Button b;
public void changecolor() {
// btn.Image = global::Practice.Properties.Resources.Untitled_1;
while (_CanRun)
{
//do what you need todo
Thread.Sleep(300);//here you could use AutoResetEvent with the Set method to avoid
//having to wait, you can also use Thread.Abort but that will cause an
//exception
}
}
public bool isChange {
get{ return t;}
set{
t= value;
change = value;
}
}
public Button getButton {
get {return b;}
set {b = value;}
}
}
这将使线程正常退出.
在这里,您应该从
的主目录调用stopThread
This will let the thread exit gracefully.
Here you should call the stopThread from the main from
//you should add this using
//using System.Collections.Generic;
private List<monitor> MonitorList = new List<monitor>();
/* This is the Main form that is being displayed and it contains a flowlayout */
public Main()
{
InitializeComponent();
//this event can be added using your property tab/events of the form.
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(Main_FormClosing);
/* a flowlayoutpanel attached at the main form */
flowLayoutPanel1.AutoScroll = true;
flowLayoutPanel1.Dock = DockStyle.Fill;
Monitor oMonitorTemp = null;
for (int i = 0; i < 10; i++)
{
oMonitorTemp = new Monitor();
//flowLayoutPanel1.Controls.Add(createButton((i+1) + ""));
flowLayoutPanel1.Controls.Add(oMonitorTemp);
//adding to list to be able to keep track of all objects
//you can also go through all the controls in flowLayoutPanel1
//and check which ones are of type Monitor
MonitorList.Add(oMonitorTemp);
}
}
private void Main_FormClosing(object sender, FormClosingEventArgs e)
{
foreach (Monitor mon in MonitorList)
{
mon.StopThread();
}
}
/*End of main form */
</monitor></monitor>
您还应该查看 AutoResetEvent
尝试此链接-> http://msdn.microsoft.com/en-us/library/system.threading. autoresetevent.aspx [ ^ ]
问候
Terence
You should also look at AutoResetEvent
Try this link -> http://msdn.microsoft.com/en-us/library/system.threading.autoresetevent.aspx[^]
Regards
Terence
在启动线程之前执行此操作:
Do this before starting the thread:
thread.IsBackground = true;
从MSDN:背景线程与前景线程相同,只是背景线程不会阻止进程终止.
http://msdn.microsoft.com/en-us/library/system. threading.thread.isbackground.aspx [ ^ ]
但是请注意您的线程功能.您不应更改或使用来自不同线程的任何UI控件.看看InvokeRequired
,Invoke
和BeginInvoke
.
From MSDN: Background threads are identical to foreground threads, except that background threads do not prevent a process from terminating.
http://msdn.microsoft.com/en-us/library/system.threading.thread.isbackground.aspx[^]
But be careful about your thread function. You shouldn''t change or use any UI controls from a different thread. Have a look to InvokeRequired
, Invoke
and BeginInvoke
.
使用 ^ ]用于关闭应用程序的方法.
Use Application.Exit
[^] method for closing the application.
这篇关于C#:阻止主线程运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!