编辑:我从.Sleep(5000)
方法中删除了Run()
,并用模拟复杂计算的双循环替换了它。
我想了解如何使用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();
}
}
}
运行程序时,线程未启动:
Thread status: Unstarted Enter command line (Start/Wait/Set/Status/Quit)
启动线程后,事情变得很奇怪。 ThreadState
立即从运行更改为WaitSleepJoin。是什么原因呢?我以为线程将保持其运行状态,直到我们调用方法WaitOne()
。
编辑:线程启动,其ThreadState
在逻辑上为Running
Thread status: Unstarted Enter command line (Start/Wait/Set/Status/Quit) start Thread status: Running Enter command line (Start/Wait/Set/Status/Quit) This engine is working hard!!! status >Running
然后,当我输入Wait时,线程停留在WaitSleepJoin中,但是引擎继续运行。
编辑:我现在遇到的问题是如何停止它?当我打电话
Engine.ThreadHandle.WaitOne(Timeout.Infinite);
线程继续运行:
Thread status: Unstarted Enter command line (Start/Wait/Set/Status/Quit) start Thread status: Running Enter command line (Start/Wait/Set/Status/Quit) This engine is working hard!!! status >Running Thread status: Running Enter command line (Start/Wait/Set/Status/Quit) This engine is working hard!!! wait Thread status: Running
最后,当我键入Set时,线程永远不会回到运行状态。
我的问题仍然是:
Engine
的线程WaitOne()
托架?答案 0 :(得分:0)
在执行代码(两个for循环)之后,您的WaitOne()
将永远不会像在主循环中那样工作。
您需要将其向下移动:
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
。