【发布时间】:2016-07-12 18:31:20
【问题描述】:
下面是我学习C#事件调用的代码,以及其中使用线程的情况。我在使用时有几个问题:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace EventSample1
{
public class MyTimerClass
{
public event EventHandler MyElapsed;
//----
private void OnOneSecond(object source, EventArgs args)
{
if (MyElapsed != null)
{
MyElapsed(source, args);
}
}
//----
private System.Timers.Timer MyPrivateTimer;
//----
public MyTimerClass()
{
MyPrivateTimer = new System.Timers.Timer();
MyPrivateTimer.Elapsed += OnOneSecond;
//----
MyPrivateTimer.Interval = 1000;
MyPrivateTimer.Enabled = true;
}
}
//----
class classA
{
public void TimerHandlerA(object source, EventArgs args)
{
Console.WriteLine("{0} class A handler called! at thread {1}", DateTime.Now, Thread.CurrentThread.ManagedThreadId);
}
}
class classB
{
public static void TimerHandlerB(object source, EventArgs args)
{
Console.WriteLine("{0} class B handler called! at thread {1}", DateTime.Now, Thread.CurrentThread.ManagedThreadId);
}
}
//----
class Program
{
static void Main()
{
Console.WriteLine("Main thread on {0}", Thread.CurrentThread.ManagedThreadId);
classA ca = new classA();
MyTimerClass mc = new MyTimerClass();
//----
mc.MyElapsed += ca.TimerHandlerA;
mc.MyElapsed += classB.TimerHandlerB;
//----
Thread.Sleep(2250);
}
}
}
说明当mc.Elapsed被调用时,主线程开启另一个(invoke?)线程来执行两个EventHandler(TimerEventHandlerA和B)。
我的问题 1. 是:
为什么主线程标为1号,而新调用的线程标为4号? 那么,什么是2号线和3号线呢? 他们是做什么的?
然后我修改了main()中的代码,让主线程从2.25s'休眠到5.25s',
Thread.Sleep(5250);
我得到了不同的结果(另一个线程被调用):
我的问题 2。 是:
正在使用的线程数是否完全由系统决定?是人们称之为“线程池”的东西吗?
之后,我在Thread.Sleep() 之前插入另一行,看看会发生什么?
//----
mc.MyElapsed += ca.TimerHandlerA;
mc.MyElapsed += classB.TimerHandlerB;
Console.ReadLine();
//----
Thread.Sleep(2250);
我这样做的原因是:
据我了解,当事件 myElapsed 被调用时,A 和 B 将被调用。在调用它们之前,程序会使用一个新线程来执行TimerEventHandlerA和B中的代码。主线程很快就会回到readline()这一行,等待我们输入。就像我们使用Thread.Sleep()时一样,主线程刚刚回到Thread.Sleep(),并在2.25s'后关闭程序运行!
但结果不是像我们想的那样,TimerEventHandler A 和 B 只是被一次又一次地调用......就像主线程永远不会来到readline() !
我只是在同一个位置使用不同的线,为什么结果如此不同?
我认为这可能是指线程中的一些细节,但是我的书并没有过多地谈论线程在C#中的使用,有人可以推荐另一本自学的好书吗?
提前致谢!
【问题讨论】:
-
Read msdn.microsoft.com/de-de/library/… - 事件被调用的线程上下文取决于定时器本身。你只能依赖:a)它会被调用 b)它不会在主线程上下文中被调用
-
如果您将这些问题作为三个单独的问题重新发布,您可能会得到这些问题的答案。现在它有点太宽泛了。
-
@Enigmativity 感谢您的建议!可能你可以先给出一两个你觉得舒服的答案吗?谢谢!
-
@SirRufo 感谢您的回复!但首先,你能告诉我你回答哪个问题吗?第一个?第二个?还是第三个?
标签: c# multithreading