English 中文(简体)
事件增多与直接方法不同
原标题:Raising events vs direct method calls differences
  • 时间:2010-04-18 00:52:27
  •  标签:
  • c#
最佳回答

Raising an event, will call its event handler

这开始是错误的。 可使用no活动手稿。 或很多。 你们不知道。 这与直接使用一种方法有很大不同。 查阅贵方设计书的“观察模式”。

问题回答

差异在于:

Event rise = “如果任何人在聆听和照料时,情况就是如此。”

它对分离关切和可复用性至关重要。 如果点击某一种特定方法,则纽芬兰并非可再使用的组成部分。 但是,如果它只是方案中的“announces”,它就被点击,而有关各方有责任对此进行指责,那么它肯定是可适用的。

如何做到这一点的基本技术执行(通过代表)是毫不相干的。

What is the difference between using the events mechanism and direct calls to other methods (eg if a condition is met in method A(), call B() )?

商业逻辑是明智的,两者之间没有差别。 我的意思是,你能够以同样的方式完成同样的任务。 它只是一种不同的方式。 真正的差别是你处理其他单元通知的工作量。

在提出一项事件时,你基本上说,“他曾经发生过任何守则,在出现时已签署并通知,让他们知道。 得到通知的哪些模块不是我所关切的,因为我假定(在时间上)所有需要知道的单元都是为通知而设置的。

在直接使用每一种方法后,你决定,你将告诉这些单元(或这些单元),而只是这些单元发生了。 你们声称,无论这些单元的状态如何,都没有任何重要意义,他们需要知道这一事件。

两种情况都是正确的。 事件通知更有活力。 不同的模块可以登记和取消通知登记。 直接方法电话更为静态。 某些物体(或模块等)绝对要通知(禁止某些例外情况)已经发生,但只通知它们。

举办活动(或发誓,从您的链接中使用这一术语)意味着你将活动送给所有消费者。 例如,当窗户被点火时,窗户可以提出事件。

假设一项事件,就意味着你接受并处理由谁发送的事件。 例如,你可能想知道窗户何时被 mo点击。

如果只有一位消费者,那么你可以直接提供反馈,从而完成类似的工作:

//  Event  type:
delegate void DelMyEvent();
// consumer:
class Consumer
{
    Producer _theProducer;
    void RegisterForNotification()
    {
       _theProducer.OnMyEvent = new DelMyEvent(OnMyEvent);
    }
    void OnMyEvent() { }
}
// producer:
class Producer
{
   public DelMyEvent OnMyEvent;
   void SendNotification()
   {
      if( OnMyEvent != null ) OnMyEvent();
   }
}

这一活动机制通过阻止消费者直接确定代表价值来清理这一界限。 相反,它使消费者登记在+=的操作人手中。 当第一个消费者登记册时,该代表就开始登记,在第二个消费者登记册上,他们的两个反馈通过<代码>Delegate.Combine合并。

For anyone, who is interested in the performance of event call, I have made this simple benchmark. It shows the differences between calling a method directly, calling it via interface, via delegate and via event, where one handler is attached.

在每一种情况下,采用相应方法为1 000 000次。 这里是(可能令人惊讶的)成果:

代表电话: 23 240 ms - 最快

活动电话: 23 295

直接电话: 23 396 ms

电话: 23 716 ms - 速度最慢

利用C#在NET4.0中的C#,在释放过程中做了一些改进。

守则如下:

class Program
{
    static void Main(string[] args)
    {
        TestClass.RunTest();
        Console.ReadLine();
    }
}

interface ITestClass
{
    void TestMethod(object sender, TestEventArgs eventErgs);
}

class TestClass : ITestClass
{
    #region Events

    event EventHandler<TestEventArgs> TestEvent;

    #endregion

    #region Constructor

    public TestClass()
    {
        TestEvent += TestMethod;
    }

    #endregion

    #region Public Methods

    public static void RunTest()
    {
        int testCount = 1000000000; //1 000 000 000

        string format = "{0:### ### ### ##0}";

        #region Direct Call

        Console.WriteLine("Direct call");
        TestClass testClass = new TestClass();

        testClass.TestMethod(testClass, new TestEventArgs(3));

        Stopwatch stopwatch = Stopwatch.StartNew();
        for (int i = 0; i < testCount; ++i)
        {
            testClass.TestMethod(testClass, new TestEventArgs(3));
        }
        stopwatch.Stop();
        Console.WriteLine(string.Format(format, stopwatch.ElapsedMilliseconds));
        Console.WriteLine();

        #endregion

        #region Interface Call

        Console.WriteLine("Interface call");
        ITestClass itestClass = new TestClass();
        itestClass.TestMethod(testClass, new TestEventArgs(3));

        stopwatch = Stopwatch.StartNew();
        for (int i = 0; i < testCount; ++i)
        {
            itestClass.TestMethod(testClass, new TestEventArgs(3));
        }
        stopwatch.Stop();
        Console.WriteLine(string.Format(format, stopwatch.ElapsedMilliseconds));
        Console.WriteLine();

        #endregion

        #region Delegate Call

        Console.WriteLine("Delegate call");
        TestClass delegateTestClass = new TestClass();
        Action<object, TestEventArgs> delegateMethod = delegateTestClass.TestMethod;
        delegateMethod(testClass, new TestEventArgs(3));

        stopwatch = Stopwatch.StartNew();
        for (int i = 0; i < testCount; ++i)
        {
            delegateMethod(testClass, new TestEventArgs(3));
        }
        stopwatch.Stop();
        Console.WriteLine(string.Format(format, stopwatch.ElapsedMilliseconds));
        Console.WriteLine();

        #endregion

        #region Event Call

        Console.WriteLine("Event call");
        TestClass eventTestClast = new TestClass();
        eventTestClast.TestEvent(testClass, new TestEventArgs(3));

        stopwatch = Stopwatch.StartNew();
        for (int i = 0; i < testCount; ++i)
        {
            eventTestClast.TestEvent(testClass, new TestEventArgs(3));
        }
        stopwatch.Stop();
        Console.WriteLine(string.Format(format, stopwatch.ElapsedMilliseconds));
        Console.WriteLine();

        #endregion
    }

    #endregion

    #region ITestClass Members

    public void TestMethod(object sender, TestEventArgs e)
    {
        e.Result = e.Value * 3;
    }

    #endregion
}

class TestEventArgs : EventArgs
{
    public int Value { get; private set; }

    public int Result { get; set; }

    public TestEventArgs(int value)
    {
        Value = value;
    }
}




相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签