C# 如何停止线程?
嗨,伙计们,我用这样的代码开始线程:C# 如何停止线程?,c#,multithreading,C#,Multithreading,嗨,伙计们,我用这样的代码开始线程: Thread[] thr; private void button1_Click(object sender, EventArgs e) { decimal value = numericUpDown2.Value; int i = 0; threads_count = (int)(value); thr = new Thread[threads_count];
Thread[] thr;
private void button1_Click(object sender, EventArgs e)
{
decimal value = numericUpDown2.Value;
int i = 0;
threads_count = (int)(value);
thr = new Thread[threads_count];
for (; i < threads_count; i++)
{
thr[i] = new Thread(new ThreadStart(go));
thr[i].IsBackground = true;
thr[i].Start();
}
}
Thread[]thr;
私有无效按钮1\u单击(对象发送者,事件参数e)
{
十进制值=numericUpDown2.值;
int i=0;
线程数=(int)(值);
thr=新线程[线程数];
对于(;i
如果我的条件变为真,如何停止所有线程(不推荐)-使用方法中止线程。此方法在线程上引发ThreadAbortException。像这样:
foreach(Thread thread in thr)
thread.Abort();
但更好的方法是通知线程取消并让它正确完成其工作。您只需使用.Net 4任务即可完成此任务:
Task[] thr = new Task[threads_count];
var source = new CancellationTokenSource();
for (int i = 0; i < threads_count; i++)
{
thr[i] = Task.Factory.StartNew(go, source.Token);
}
// later, when condition is met
source.Cancel();
野蛮方式(不推荐)-使用方法中止线程。此方法在线程上引发ThreadAbortException。像这样:
foreach(Thread thread in thr)
thread.Abort();
但更好的方法是通知线程取消并让它正确完成其工作。您只需使用.Net 4任务即可完成此任务:
Task[] thr = new Task[threads_count];
var source = new CancellationTokenSource();
for (int i = 0; i < threads_count; i++)
{
thr[i] = Task.Factory.StartNew(go, source.Token);
}
// later, when condition is met
source.Cancel();
简单的答案是使用thread Abort()方法,但是您的代码并没有真正弄清楚是什么条件
什么循环测试与条件?为什么需要中止线程?我这样问是因为可能有更好的方法来解决这个问题。简单的答案是使用thread Abort()方法,但是您的代码并没有真正说明什么条件
什么循环测试与条件?为什么需要中止线程?我在问,因为可能有更好的方法来实现这一点如果您想知道如何优雅地终止线程,我建议您查看以下内容:
如果您想知道如何优雅地终止线程,我建议您查看以下内容:
您可以使用
CancellationToken
发出操作应停止的信号
CancellationTokenSource
作为您在按钮单击处理程序中初始化的类型的实例字段令牌
的IsCancellationRequested
属性,或者调用throwifcCancellationRequested()
,如果希望它在取消时只抛出异常Cancel
您可以使用
CancellationToken
发出操作应停止的信号
CancellationTokenSource
作为您在按钮单击处理程序中初始化的类型的实例字段令牌
的IsCancellationRequested
属性,或者调用throwifcCancellationRequested()
,如果希望它在取消时只抛出异常Cancel
许多答案都说要中止线程切勿中止线程,除非是紧急情况并且您正在关闭应用程序 CLR保证其内部数据结构不会因线程中止而损坏这是CLR对线程中止做出的唯一(*)保证。它具体不保证:
- 线程实际上将中止。螺纹会硬化,以防被终止李>
- 任何不在CLR中的数据结构都不会被损坏。在关键操作的中间,线程中止可以在任意不一致的状态中留下BCL数据结构或用户数据结构。这可能会在以后神秘地使您的进程崩溃
- 锁将被释放。中止线程可能会导致锁永久保留,也可能导致死锁,等等
任务
,当您想关闭它时,用信号通知它的取消令牌
如果您确实需要启动线程,那么启动线程,这样就有了某种机制,主线程和工作线程可以干净、安全地通信“我希望您在这个时候干净地关闭自己”
如果您不知道如何做到这一点,那么停止编写多线程代码,直到您学会如何做到这一点
(*)这是一个小谎言;CLR还对线程中止和特殊代码区域(如受约束的执行区域和最终块)的交互做出某些保证。许多答案都说要中止线程切勿中止线程,除非是紧急情况并且您正在关闭应用程序 CLR保证其内部数据结构不会因线程中止而损坏这是CLR对线程中止做出的唯一(*)保证。它具体不保证:
- 线程实际上将中止。螺纹会硬化,以防被终止李>
- 任何不在CLR中的数据结构都不会被损坏。在关键操作的中间,线程中止可以在任意不一致的状态中留下BCL数据结构或用户数据结构。这可能会在以后神秘地使您的进程崩溃
- 锁将被释放。中止线程可能会导致锁永久保留,也可能导致死锁,等等
namespace Thread_TerminateProblem
{
public partial class Form1 : Form
{
private static AutoResetEvent m_ResetEvent = null;
private static ManualResetEvent m_ResetEvent_Thread = new ManualResetEvent(false);
enum ServiceState { Start, Stop };
bool flag = false;
int x = 0;
ServiceState _state;
public Form1()
{
InitializeComponent();
}
private void btnStart_Click(object sender, EventArgs e)
{
flag = true;
_state = ServiceState.Start;
m_ResetEvent = new AutoResetEvent(true);
Thread t1 = new Thread(fun_Thread1);
t1.Start();
t1.Name = "Thread1";
}
private void btnStop_Click(object sender, EventArgs e)
{
_state = ServiceState.Stop;
m_ResetEvent.Set();
}
private void fun_Thread1()
{
while (true)
{
m_ResetEvent.WaitOne();
switch (_state)
{
case ServiceState.Start:
{
Thread t = new Thread(fun_Thread2);
t.Start();
t.Name = "Thread2";
break;
}
case ServiceState.Stop:
{
m_ResetEvent_Thread.Set();
flag = true;
break;
}
}
// When the child Thread terminates, Then only this thread should terminate
if (flag == true)
{
// Waiting for notification from child Thread
notifyParent.WaitOne();
Thread.Sleep(100);
break;
}
m_ResetEvent.Reset();
}
}
private static ManualResetEvent notifyParent = new ManualResetEvent(false);
private void fun_Thread2()
{
while (true)
{
if (m_ResetEvent_Thread.WaitOne(1, false))
{
notifyParent.Set();
break;
}
x++;
}
}
}