线程阻塞

shorter 2008-04-18 03:19:22

Thread thread = new Thread(Method);
thread.Start();
//thread.Join();
while (thread.ThreadState != ThreadState.Stopped && thread.ThreadState != ThreadState.Suspended)
{ }


需求:在线程没有被中止且没有被被挂起时阻塞当前线程

问题:使用thread.Join()只有在线程中止时才停止阻塞当前线程。我是想如果线程被挂起时也停止阻塞。
所以使用了while循环解决这问题,但这样消耗Cpu资源明显更多,不知道有没有好的解决方法?
...全文
147 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
jamesfay 2008-04-18
  • 打赏
  • 举报
回复
用AutoResetEvent
http://msdn2.microsoft.com/en-us/library/system.threading.autoresetevent.aspx


using System;
using System.Threading;

class CalculateTest
{
static void Main()
{
Calculate calc = new Calculate();
Console.WriteLine("Result = {0}.",
calc.Result(234).ToString());
Console.WriteLine("Result = {0}.",
calc.Result(55).ToString());
}
}

class Calculate
{
double baseNumber, firstTerm, secondTerm, thirdTerm;
AutoResetEvent[] autoEvents;
ManualResetEvent manualEvent;

// Generate random numbers to simulate the actual calculations.
Random randomGenerator;

public Calculate()
{
autoEvents = new AutoResetEvent[]
{
new AutoResetEvent(false),
new AutoResetEvent(false),
new AutoResetEvent(false)
};

manualEvent = new ManualResetEvent(false);
}

void CalculateBase(object stateInfo)
{
baseNumber = randomGenerator.NextDouble();

// Signal that baseNumber is ready.
manualEvent.Set();
}

// The following CalculateX methods all perform the same
// series of steps as commented in CalculateFirstTerm.

void CalculateFirstTerm(object stateInfo)
{
// Perform a precalculation.
double preCalc = randomGenerator.NextDouble();

// Wait for baseNumber to be calculated.
manualEvent.WaitOne();

// Calculate the first term from preCalc and baseNumber.
firstTerm = preCalc * baseNumber *
randomGenerator.NextDouble();

// Signal that the calculation is finished.
autoEvents[0].Set();
}

void CalculateSecondTerm(object stateInfo)
{
double preCalc = randomGenerator.NextDouble();
manualEvent.WaitOne();
secondTerm = preCalc * baseNumber *
randomGenerator.NextDouble();
autoEvents[1].Set();
}

void CalculateThirdTerm(object stateInfo)
{
double preCalc = randomGenerator.NextDouble();
manualEvent.WaitOne();
thirdTerm = preCalc * baseNumber *
randomGenerator.NextDouble();
autoEvents[2].Set();
}

public double Result(int seed)
{
randomGenerator = new Random(seed);

// Simultaneously calculate the terms.
ThreadPool.QueueUserWorkItem(
new WaitCallback(CalculateBase));
ThreadPool.QueueUserWorkItem(
new WaitCallback(CalculateFirstTerm));
ThreadPool.QueueUserWorkItem(
new WaitCallback(CalculateSecondTerm));
ThreadPool.QueueUserWorkItem(
new WaitCallback(CalculateThirdTerm));

// Wait for all of the terms to be calculated.
WaitHandle.WaitAll(autoEvents);

// Reset the wait handle for the next calculation.
manualEvent.Reset();

return firstTerm + secondTerm + thirdTerm;
}
}
gomoku 2008-04-18
  • 打赏
  • 举报
回复
放一个事件机,线程推出前扳动一下;
要暂停线程总要一个地方调用Thread.Suspend对不对?调用的时候也扳动一下。


Thread thread = new Thread(Method);
ManualResetEvent threadStopped = new ManualResetEvent(false);

//......
thread.Start();
threadStopped.WaitOne(); //<--阻塞

//.......
thread.Suspend();
threadStopped.Set();

//.......
void Method()
{
//...
//...

threadStopped.Set();
return;
}


建议不要用Thread.Suspend来做同步,总会有其他更好办法。

110,539

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧