使用事件机制与直接使用其他方法之间有何区别(例如,如果在方法A(a)中满足条件,称为B(b)))?
消费与制造活动之间的差别如何?
增 编
Raising an event, will call its event handler
这开始是错误的。 可使用
差异在于:
它对分离关切和可复用性至关重要。 如果点击某一种特定方法,则纽芬兰并非可再使用的组成部分。 但是,如果它只是方案中的“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;
}
}
除了上述多种/无用户设想之外,还利用一些活动来减少代号政变,例如,A()方法在汇编时间时不必知道有关方法B()的任何情况。 这使得人们能够更好地把关切分开,减少脆弱的法典。
在野生动物中,你更可能看到框架和标准中使用的事件,而在应用开发商的领域逻辑中,更经常使用诸如:;Separated Interface 和Domain Activities。
What is the use of default keyword in C#? Is it introduced in C# 3.0 ?
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. ...
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 ...
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 ...
I have two EF entities. One has a property called HouseNumber. The other has two properties, one called StartHouseNumber and one called EndHouseNumber. I want to create a many to many association ...
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, ...
Since I cannot order my dictionary, what is the best way of going about taking key value pairs and also maintaing an index?
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. ...