c#线程学习之ManualResetEvent和AutoResetEvent的区别

c#线程学习之ManualResetEvent和AutoResetEvent的区别

我理解线程间通讯问题接收a候主线程创建新线程运行函数(比叫WorkRun)新线程(比叫thA)运行主线程接收b需要通知thA使止或改变其运行逻辑

启线程写:

Thread thA = new Thread(new ThreadStart(WorkRun));

thA.Start();

事实两种能场景第种主线程向thA发送止线程指令让函数止执行;另种函数执行某点候停等待主线程给信号决定该执行逻辑

1. 止线程需要接收b候写

if(thA.ThreadState == ThreadState.Running)

{

thA.Abort();

}

2. 需要运行停等待主线程指令使用ManualResetEventManualResetEvent 允许线程通发信号互相通信通通信涉及线程其线程进行前必须完任务

线程始(必须完其线程才能始)调用 Reset ManualResetEvent 置于非终止状态线程视控制 ManualResetEvent调用 ManualResetEvent WaitOne 线程阻止并等待信号控制线程完调用 Set 发等待线程继续进行信号并释放所等待线程

旦终止ManualResetEvent 保持终止状态直手重置即 WaitOne 调用立即返

通布尔值传递给构造函数控制 ManualResetEvent 初始状态初始状态处于终止状态 true;否则 false

ManualResetEvent 同 staticWaitAll WaitAny 起使用

实例(面代码示例阐释何使用等待句柄发送复杂数字计算同阶段完信号计算格式:结 = 第项 + 第二项 + 第三项其每项都要求使用计算基数进行预计算终计算):

using System;

using System.Threading;

class CalculateTest

{

static void Main()

{

Calculate calc = new Calculate();

Console.WriteLine("Result = .",

calc.Result(234).ToString());

Console.WriteLine("Result = .",

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.Set();

}

void CalculateSecondTerm(object stateInfo)

{

double preCalc = randomGenerator.NextDouble();

manualEvent.WaitOne();

secondTerm = preCalc * baseNumber *

randomGenerator.NextDouble();

autoEvents.Set();

}

void CalculateThirdTerm(object stateInfo)

{

double preCalc = randomGenerator.NextDouble();

manualEvent.WaitOne();

thirdTerm = preCalc * baseNumber *

randomGenerator.NextDouble();

autoEvents.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;

}

}