编辑:我已经从Run()
方法中删除了.Sleep(5000)
,并将其替换为模拟复杂计算的双循环。
我想了解如何用ManualResetEvent
控制线程? 我写了那段简单的代码,它应该启动、停止和恢复前台线程,但它没有按预期工作。
using System;
using System.Threading;
namespace ThreadHandler
{
public class Engine
{
public static ManualResetEvent ThreadHandle;
public static void Run()
{
Random rng = new Random();
ThreadHandle = new ManualResetEvent(true);
while (true)
{
ThreadHandle.WaitOne();
for (int i = Int32.MaxValue; i > 0; i--)
{
for (int j = 0; j < rng.Next(); j++)
{
int res;
int div =
Math.DivRem(Math.Abs(Convert.ToInt32(Math.Floor(Math.Log(rng.NextDouble()) /
Math.Log(rng.NextDouble())))),
Math.Abs(Convert.ToInt32(Math.Floor(Math.Log(rng.NextDouble()) /Math.Log(rng.NextDouble())))) + 1, out res);
double calc = Math.Sin(Math.Sqrt(div)) * Math.Cos(Math.Sqrt(res));
}
if (i % 500 == 0)
Console.WriteLine("This engine is working hard!!!");
}
}
}
}
public class Program
{
static void Main(string[] args)
{
Thread engine = new Thread(Engine.Run);
int cnt = 100;
while (cnt-- > 0)
{
Console.WriteLine("nThread status: " + engine.ThreadState);
Console.WriteLine("Enter command line (Start/Wait/Set/Status/Quit)");
string cmd = Console.ReadLine();
switch(cmd.ToUpper())
{
case "START":
engine.Start();
break;
case "WAIT":
Engine.ThreadHandle.WaitOne(Timeout.Infinite);
break;
case "SET":
Engine.ThreadHandle.Set();
break;
case "STATUS":
Console.WriteLine(" >" + engine.ThreadState);
break;
case "QUIT":
cnt = 0;
break;
default:
Console.WriteLine("Unknown command");
break;
}
}
engine.Abort();
}
}
}
当我运行程序时,线程已取消启动:
线程状态:未启动 输入命令行(启动/等待/设置/状态/退出(
ThreadState
立即从"正在运行"更改为"等待睡眠加入"。这是什么原因呢?我以为线程将保持其运行状态,直到我们将该方法称为 WaitOne()
.编辑:线程启动,其ThreadState
在逻辑上Running
线程状态:未启动 输入命令行(启动/等待/设置/状态/退出( 开始 线程状态:正在运行 输入命令行(启动/等待/设置/状态/退出( 这个引擎正在努力工作!! 地位>运行
编辑:我现在遇到的问题是我如何阻止它?当我打电话时
Engine.ThreadHandle.WaitOne(Timeout.Infinite);
线程保持运行:
线程状态:未启动 输入命令行(启动/等待/设置/状态/退出( 开始 线程状态:正在运行 输入命令行(启动/等待/设置/状态/退出( 这个引擎正在努力工作!! 地位>跑步 线程状态:正在运行 输入命令行(启动/等待/设置/状态/退出( 这个引擎正在努力工作!! 等 线程状态:运行
我的问题仍然是:
- 如何中断调用方法
WaitOne()
的线程Engine
托架? - 之后如何恢复?
你的WaitOne()
永远不会工作,因为它在主循环中,而代码执行在后面(两个for循环(。
您需要将其向下移动:
while (true)
{
for (int i = Int32.MaxValue; i > 0; i--)
{
for (int j = 0; j < rng.Next(); j++)
{
ThreadHandle.WaitOne();
// ...
}
if (i % 500 == 0)
Console.WriteLine("This engine is working hard!!!");
}
}
结果
Thread status: WaitSleepJoin
Enter command line (Start/Wait/Set/Status/Quit)
请注意
,我相信您错误地使用了ManualResetEvent
因为WaitOne
方法需要由谁将等待(在您的情况下为 Thread(调用,但您调用了两次。您可能应该使用布尔值向线程发出信号,表明它应该启动WaitOne
。