关于线程在事件被使用在C#中调用 [英] About Threads Being Used in the Event Calling in C#

查看:191
本文介绍了关于线程在事件被使用在C#中调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是我用来学习事件在C#中调用代码,和线程的情况,它被使用。我使用时,有几个问题:

 使用系统; 
使用System.Collections.Generic;
使用System.Linq的;
使用System.Text;
使用的System.Threading;

命名空间EventSample1
{
公共类MyTimerClass
{
公共事件的EventHandler MyElapsed;
// ----
私人无效OnOneSecond(对象源,EventArgs的参数)
{
如果(MyElapsed!= NULL)
{
MyElapsed (来源参数);
}
}
// ----
私人System.Timers.Timer MyPrivateTimer;
// ----
公共MyTimerClass()
{
MyPrivateTimer =新System.Timers.Timer();
MyPrivateTimer.Elapsed + = OnOneSecond;
// ----
MyPrivateTimer.Interval = 1000;
MyPrivateTimer.Enabled = TRUE;
}
}
// ----
类ClassA的
{
公共无效TimerHandlerA(对象源,EventArgs的参数)
{
Console.WriteLine({0} A级处理器调用线程在{1}!,DateTime.Now,Thread.CurrentThread.ManagedThreadId);
}
}
级ClassB的
{
公共静态无效TimerHandlerB(对象源,EventArgs的参数)
{
Console.WriteLine( {0}称为B类处理器在线程{1},DateTime.Now,Thread.CurrentThread.ManagedThreadId)!;
}
}
// ----
类节目
{
静态无效的主要()
{
控制台.WriteLine(,Thread.CurrentThread.ManagedThreadId关于{0}主线程);
CLASSA CA =新ClassA的();
MyTimerClass MC =新MyTimerClass();
// ----
mc.MyElapsed + = ca.TimerHandlerA;
mc.MyElapsed + = classB.TimerHandlerB;
// ----
Thread.sleep代码(2250);
}
}
}



结果是这样的:



这表明,当 mc.Elapsed 被称为,主线程打开另一个(引用?)线程来执行这两个事件处理程序( TimerEventHandler A和B)。



我的问题1 的是:



为什么主线程标记为不.1,但新调用的线程标记为4号?
那么,什么是2,3号线?
他们做些什么?






然后,我改变了我的代码在main()为了让从2.25s至5.25s,

  Thread.sleep代码(5250)主线程睡眠; 

和我得到不同的结果(被调用另一个线程):





我的第二个问题。的是,



<强>是否使用线程数完全由系统决定?它是人们所谓的线程池这样做吗?






在这之后,我插入一行在 Thread.sleep代码()来看看有什么发生?

  / / ---- 
mc.MyElapsed + = ca.TimerHandlerA;
mc.MyElapsed + = classB.TimerHandlerB;
到Console.ReadLine();
// ----
Thread.sleep代码(2250);



我这样做的原因是:



据我了解,当事件myElapsed被称为A和b将被调用。他们被称为前,程序将使用一个新的线程在 TimerEventHandler A和B. 执行代码和主线程很快就会回到的ReadLine()行,等待我们去投入。就像当我们使用 Thread.sleep代码()主线程刚回来的 Thread.sleep代码()后2.25s关闭程序运行!



但结果是不会像什么,我们认为,在 TimerEventHandler A和B只是一次又一次地叫......像主线程不会来的ReadLine()



我只是用在同样的位置,为什么结果是如此不同不同的线路?



我想这可能指的是线程的一些细节,但我的书并没有过多谈论使用C#线程,任何人都可以推荐另一本好书自学?



在此先感谢!


解决方案

为什么主线程被打成号1,但新调用的线程标记为4号?那么,什么是2,3号线?他们会怎么做?



不要在意线程ID。




  • 每个线程都有一个唯一的ID

  • System.Timers.Timer 将调用计时器事件中的一个线程的(它可以是除主线程的任何线程)

  • System.Timers.Timer


所以我们只能依赖于该事件将被称为$ C>可以使用尽可能多的线程并且调用线程将有不同的ID比主线程。



是正在使用的线程数由系统完全决定?它是人们所谓的线程池这样做吗?



是的,它是由实施 System.Timers.Timer 计时器事件是如何被调用。我们真的不知道,如果有涉及到线程池,但它真的很重要?只要实例的行为如记录/预期我不关心的实现。



如果我不关心实现我只是来看看的来源来看看什么是引擎盖下发生。



...像主线程不会来到Console.ReadLine()



那么主线程将达到该行是肯定的。但什么是到Console.ReadLine()真的?



这是一个从输入的用户,然后等待和意志继续当用户按下<大骨节病> ENTER 。所以,直到你按下<大骨节病> ENTER 主线程被阻塞。但所有其他线程仍在运行,并调用将输出一些文本到控制台的事件



要证明这一点,我们只需要添加一些行:

  mc.MyElapsed + = ca.TimerHandlerA; 
mc.MyElapsed + = classB.TimerHandlerB;

Console.WriteLine(我在等待你的输入!);
到Console.ReadLine();
Console.WriteLine(谢谢你!);

Thread.sleep代码(2250);

Console.WriteLine(完了。);



 
主要在1
线我等待你的输入!
2016年7月12日7点53分40秒类称作处理!在螺纹4
2016年7月12日7时53分40秒的B类处理器调用!在螺纹4
2016年7月12日七时53分41秒的A类处理器调用!在螺纹4
2016年7月12日七时53分41秒的B类处理器调用!在螺纹4

和它会继续下去,直到你击中<大骨节病> ENTER 键。而当你打你应该看到事件的 Thread.sleep代码(2250)



<$ P $中仍称p>
2016年7月12日7时53分50秒类称作处理!在螺纹4
2016年7月12日七点53分五十秒的B类处理器调用!在螺纹4
谢谢!
2016年7月12日7时53分51秒类称作处理!在螺纹4
2016年7月12日七点53分51秒的B类处理器调用!在螺纹4
2016年7月12日7时53分52秒的A类处理器调用!在螺纹4
2016年7月12日7时53分52秒的B类处理器调用!在螺纹4
完成。



任何人都可以推荐另一本好书自学?



没有,那样的问题是在这里下车的话题上左右。


Below is the codes I used to learn the Event Calling in C#, and the situation of Threads Being Used in it. I have several questions when using it:

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);
        }
    }
}

the results is like this:

It shows that when mc.Elapsed being called, the main thread open another (invoke?) thread to perform the two EventHandler (TimerEventHandler A and B).

My Question 1. is that:

Why the main thread be labeled as No.1, but the new invoked thread be labeled as No.4? Then, what’s No.2 and No.3 thread? What do they do?


Then I changed my codes in the main(), to let the main thread sleep from 2.25s’ to 5.25s’,

Thread.Sleep(5250);

and I got different result (another thread being invoked ):

My Question 2. is that:

Is the number of threads being used totally decided by the system? Is it what people called "thread pools" to do that?


After that, I insert another line before the Thread.Sleep() to see what happen?

//----
mc.MyElapsed += ca.TimerHandlerA;
mc.MyElapsed += classB.TimerHandlerB;
Console.ReadLine();
//----
Thread.Sleep(2250);

The reason I do this is:

As I understanding, when the event myElapsed be called, A and B will be called. Before they being called, the program will use a new thread to perform the codes in TimerEventHandler A and B. And the main thread will soon get back to the readline() line and wait for us to input. Just like when we use Thread.Sleep(), the main thread just come back to the Thread.Sleep() and after 2.25s' to close the program running!

But the result is NOT like what we think, the TimerEventHandler A and B just be called again and again......like the main thread will never come to readline()!

I just use different line in the same position, why the result is so different?

I think this may refer to some details in threads, but My book does not talk much about threads using in C#, could anyone recommend another good book for self-learning?

Thanks in advance!

解决方案

Why the main thread be labeled as No.1, but the new invoked thread be labeled as No.4? Then, what’s No.2 and No.3 thread? What do they do?

Do not care about the thread id.

  • Each thread has a unique id
  • System.Timers.Timer will call the timer event inside of a thread (and it can be any thread except the main thread)
  • System.Timers.Timer can use as many threads as it needs to do its job

So we can only rely on that the event will be called and the calling thread will have a different id than the main thread.

Is the number of threads being used totally decided by the system? Is it what people called "thread pools" to do that?

Yes, it is up to the implementation of System.Timers.Timer how the timer event is called. We do not really know if there is a thread pool involved, but does it really matters? As long as the instance behaves as documented/expected I do not care about the implementation.

If I do care about the implementation I just have a look at the sources to see what is happening under the hood.

... like the main thread will never come to Console.ReadLine()!

Well the main thread will reach that line for sure. But what does Console.ReadLine() really do?

It is waiting for an input from then user and will continue when the user press ENTER. So until you press ENTER the main thread is blocked. But all other threads are still running and will call the events which will output some text to console.

To prove this we just add some lines:

mc.MyElapsed += ca.TimerHandlerA;
mc.MyElapsed += classB.TimerHandlerB;

Console.WriteLine( "I am waiting for your input!" );
Console.ReadLine();
Console.WriteLine( "Thank you!" );

Thread.Sleep(2250);

Console.WriteLine( "Finished." );

Main thread on 1
I am waiting for your input!
2016-7-12 7:53:40 class A handler called! at thread 4
2016-7-12 7:53:40 class B handler called! at thread 4
2016-7-12 7:53:41 class A handler called! at thread 4
2016-7-12 7:53:41 class B handler called! at thread 4

and it will continue until you hit the ENTER key. And when you hit you should see the events are still called during the Thread.Sleep(2250).

2016-7-12 7:53:50 class A handler called! at thread 4
2016-7-12 7:53:50 class B handler called! at thread 4
Thank you!
2016-7-12 7:53:51 class A handler called! at thread 4
2016-7-12 7:53:51 class B handler called! at thread 4
2016-7-12 7:53:52 class A handler called! at thread 4
2016-7-12 7:53:52 class B handler called! at thread 4
Finished.

could anyone recommend another good book for self-learning?

No, that kind of questions are off topic here on SO.

这篇关于关于线程在事件被使用在C#中调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆