关于异步事件的一个测试及其分析结果
因为工作中需要在多线程中使用事件,本来想在事件中抛出一个异常到主程序中,结果可想而知,失败了。于是作了如下的一个测试,看看多线程中的异常处理问题,代码如下:
using System.Runtime.InteropServices;
using System.Threading;
namespace testAsyncEvent
{
/// <summary>
/// Class1 的摘要说明。
/// </summary>
class Class1
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
Class1 c = new Class1();
Thread t = new Thread(new ThreadStart(c.Run));
t.Name = "root";
t.Start();
}
public void Run()
{
EventRaiser er0 = new EventRaiser("er0");
er0.AsyncTextChanged += new TextEvent(er0_TextChanged);
er0.SyncTextChanged += new TextEvent(er0_TextChanged);
Console.Out.WriteLine("Begin");
ThreadStart ts = new ThreadStart(er0.Run);
Thread thr = new Thread(ts);
thr.Name = "child";
thr.Start();
Console.Out.WriteLine("Thread Started");
for(int i = 0; i < 10; ++i)
{
Thread.Sleep(20);
Console.Out.WriteLine(Thread.CurrentThread.Name + ": Cycle Print");
}
if( thr.IsAlive )
thr.Join();
Console.Out.WriteLine("Ok");
Console.Out.WriteLine("Press Enter to Exit ");
Console.In.ReadLine();
}
private void er0_TextChanged(string id, string text)
{
Console.Out.WriteLine(Thread.CurrentThread.Name + "(" + id + "):\t" + text);
}
}
public delegate void TextEvent(string id, string text);
class EventRaiser
{
const int CYCLES = 3;
public event TextEvent AsyncTextChanged;
public event TextEvent SyncTextChanged;
string _id;
private int count = 0;
public EventRaiser(string id)
{
_id = id;
}
public void Run()
{
RaiseText("Enter Thread:" + Thread.CurrentThread.Name);
for(int i = 0; i < CYCLES; ++i)
{
Thread.Sleep(10);
RaiseEvent();
}
for(int i = 0; i < CYCLES; ++i)
{
RaiseEvent();
}
for(int i = 0; i < CYCLES; ++i)
{
Thread.Sleep(10);
RaiseEvent();
}
RaiseText("Exit Thread:" + Thread.CurrentThread.Name);
}
void RaiseText(string text)
{
AsyncTextChanged.BeginInvoke(_id, text, null, null);
SyncTextChanged(_id, text);
}
void RaiseEvent()
{
RaiseText(count++.ToString());
}
}
}
代码的执行结果如下:
Begin
Thread Started
root: Cycle Print
child(er0): Enter Thread:child
(er0): Enter Thread:child
root: Cycle Print
child(er0): 0
(er0): 0
(er0): 1
child(er0): 1
root: Cycle Print
(er0): 2
child(er0): 2
(er0): 3
child(er0): 3
(er0): 4
child(er0): 4
(er0): 5
child(er0): 5
(er0): 6
child(er0): 6
root: Cycle Print
(er0): 7
child(er0): 7
(er0): 8
child(er0): 8
(er0): Exit Thread:child
child(er0): Exit Thread:child
root: Cycle Print
root: Cycle Print
root: Cycle Print
root: Cycle Print
root: Cycle Print
root: Cycle Print
Ok
Press Enter to Exit ...
从结果分析,发现如果在线程中发生同步事件,则事件的发生源在同一个线程中,如果线程中发生异步事件,则该事件既不在主线程中,也不再子线程中,而是在系统的临时线程中。
但是这里有一个问题,我无法区分线程的真正不同,哪里可以取得线程号阿?谁能告诉我,这样有线程号的区别,这个例子可以更清楚一些。
公众号:老翅寒暑