一、背景
在使用C# Winform编写程序时,有时候我们需要在关闭窗体的时候同时结束线程。但是在代码实现中,由于线程和UI控件属于不同的线程,因此需要注意一些细节问题。下面是具体的实现思路。
二、实现思路
1.启动线程
我们需要在用户打开窗体的时候启动线程。这个步骤可以放在窗体的Load事件中:
private Thread workThread;
private void Form_Load(object sender, EventArgs e)
{
workThread = new Thread(new ThreadStart(WorkThreadFunction));
workThread.IsBackground = true;
workThread.Start();
}
这里需要注意的是,我们需要将线程的IsBackground属性设置为true,这样在窗体关闭的时候,线程会自动结束。
2.关闭线程
为了关闭线程,我们需要在窗体关闭的时候停止线程。这个可以放在窗体的Closing事件中:
private void Form_Closing(object sender, FormClosingEventArgs e)
{
if (workThread != null && workThread.IsAlive)
{
workThread.Abort();
}
}
这里需要注意的是,我们需要先判断线程是否还在运行,如果线程已经结束,或者没有运行,直接忽略这个操作,否则我们可以使用Thread.Abort()方法终止线程。
3.处理线程中的UI控件
在线程中操作UI控件会引发线程安全问题,因此如果我们需要在线程中操作UI控件,需要使用Invoke方法:
private void WorkThreadFunction()
{
while (true)
{
//处理线程逻辑
if (this.InvokeRequired)
{
this.Invoke(new Action(() =>
{
//操作UI控件
}));
}
else
{
//操作UI控件
}
}
}
在这个示例中,我们使用了Invoke方法来处理UI控件,这样就可以避免线程安全问题。
三、示例说明
1.简单示例
下面是一个简单的示例,演示了如何在Winform关闭的时候结束线程。
using System;
using System.Threading;
using System.Windows.Forms;
namespace WinformCloseThread
{
public partial class Form1 : Form
{
private Thread workThread;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
workThread = new Thread(WorkThreadFunction);
workThread.IsBackground = true;
workThread.Start();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (workThread != null && workThread.IsAlive)
{
workThread.Abort();
}
}
private void WorkThreadFunction()
{
while (true)
{
//处理线程逻辑
if (this.InvokeRequired)
{
this.Invoke(new Action(() =>
{
//操作UI控件
}));
}
else
{
//操作UI控件
}
}
}
}
}
2.使用BackgroundWorker
BackgroundWorker类是.NET提供的一个异步操作类,非常适合在Winform编程中使用。下面是一个使用BackgroundWorker类的示例:
using System;
using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;
namespace WinformCloseThread
{
public partial class Form2 : Form
{
private BackgroundWorker worker;
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
worker = new BackgroundWorker();
worker.WorkerReportsProgress = true;
worker.WorkerSupportsCancellation = true;
worker.DoWork += Worker_DoWork;
worker.ProgressChanged += Worker_ProgressChanged;
worker.RunWorkerCompleted += Worker_RunWorkerCompleted;
worker.RunWorkerAsync();
}
private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
if (worker != null && worker.IsBusy)
{
worker.CancelAsync();
e.Cancel = true;
}
}
private void Worker_DoWork(object sender, DoWorkEventArgs e)
{
var worker = sender as BackgroundWorker;
while (!worker.CancellationPending)
{
//处理异步操作
worker.ReportProgress(0, "操作完成");
Thread.Sleep(1000);
}
e.Cancel = true;
}
private void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
//更新UI控件
}
private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
MessageBox.Show(e.Error.Message);
}
if (!e.Cancelled)
{
MessageBox.Show("操作已完成");
}
this.Close();
}
}
}
在这个示例中,我们使用了BackgroundWorker类来执行异步操作。由于BackgroundWorker内部封装了线程安全的操作,因此在编写代码的时候比较简单。在窗体关闭的时候我们调用CancelAsync方法来停止异步操作,然后在RunWorkerCompleted事件中关闭窗体。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:c# winform 关闭窗体时同时结束线程实现思路 - Python技术站