如何使异常处理程序异步运行? [英] How do I make an eventhandler run asynchronously?
问题描述
class TestClass
{
private Thread SecondaryThread ;
public event EventHandler OperationFinished;
public void StartMethod()
{
...
SecondaryThread.Start(); //启动次要线程
}
private void SecondaryThreadMethod()
{
...
OperationFinished(null,new EventArgs());
... //这是程序在触发OperationFinished时等待任何操作取
//的地方。
}
}
此代码是API的一部分我的一个设备。当OperationFinished事件被触发时,我希望客户端应用程序能够执行所需的任何操作(即相应地更新GUI),而不会窃取API操作。
另外,如果我不想传递任何参数到事件处理程序,我的语法正确使用 OperationFinished(null,new EventArgs() )
?
所以你想以一种防止监听者阻止的方式来引发事件后台线程? im me几分钟,举起一个例子;这很简单: - )
这里我们去:首先是重要的说明!每当你打电话 BeginInvoke
你必须调用相应的 EndInvoke
,否则如果调用的方法抛出异常,那么返回一个值,那么ThreadPool线程永远不会释放回池,导致线程泄漏!
class TestHarness
{
static void Main(string [] args)
{
var raiser = new SomeClass();
//模拟一些事件监听器
raiser.SomeEvent + =(sender,e)=> {Console.WriteLine(Received event); };
raiser.SomeEvent + =(sender,e)=>
{
//糟糕的听众!
Console.WriteLine(Blocking event);
System.Threading.Thread.Sleep(5000);
Console.WriteLine(完成阻塞事件);
};
//抛出异常的侦听器
raiser.SomeEvent + =(sender,e)=>
{
Console.WriteLine(Received event,time to die!);
抛出新的异常();
};
//提高事件,看效果
raiser.DoSomething();
Console.ReadLine();
}
}
class SomeClass
{
public event EventHandler SomeEvent;
public void DoSomething()
{
OnSomeEvent();
}
private void OnSomeEvent()
{
if(SomeEvent!= null)
{
var eventListeners = SomeEvent.GetInvocationList );
Console.WriteLine(Raising Event); (int index = 0; index< eventListeners.Count(); index ++)
{
var methodToInvoke =(EventHandler)eventListeners [index];
methodToInvoke.BeginInvoke(this,EventArgs.Empty,EndAsyncEvent,null);
}
Console.WriteLine(完成提升事件);
}
}
private void EndAsyncEvent(IAsyncResult iar)
{
var ar =(System.Runtime.Remoting.Messaging.AsyncResult)iar;
var invokedMethod =(EventHandler)ar.AsyncDelegate;
try
{
invokedMethod.EndInvoke(iar);
}
catch
{
//处理被调用方法抛出的任何异常
Console.WriteLine(事件监听器去了kaboom!);
}
}
}
I am writing a Visual C# program that executes a continuous loop of operations on a secondary thread. Occasionally when that thread finishes a task I want it to trigger an eventhandler. My program does that but the when the event handler is triggered, the secondary thread waits until the event handler is finished before continuing the thread. How do I make it continue? Here is the way I currently have it structured...
class TestClass
{
private Thread SecondaryThread;
public event EventHandler OperationFinished;
public void StartMethod()
{
...
SecondaryThread.Start(); //start the secondary thread
}
private void SecondaryThreadMethod()
{
...
OperationFinished(null, new EventArgs());
... //This is where the program waits for whatever operations take
//place when OperationFinished is triggered.
}
}
This code is part of an API for one of my devices. When the OperationFinished event is triggered I want the client application to be able to do whatever it needs to (i.e. update the GUI accordingly) without haulting the API operation.
Also, if I do not want to pass any parameters to the event handler is my syntax correct by using OperationFinished(null, new EventArgs())
?
So you want to raise the event in a manner that prevents the listeners from blocking the background thread? Gimme a couple minutes to whip up an example; it's pretty simple :-)
Here we go: first an important note! Whenever you call BeginInvoke
you must call the corresponding EndInvoke
, otherwise if the invoked method threw an exception or returned a value then the ThreadPool thread will never be released back to the pool, resulting in a thread-leak!
class TestHarness
{
static void Main(string[] args)
{
var raiser = new SomeClass();
// Emulate some event listeners
raiser.SomeEvent += (sender, e) => { Console.WriteLine(" Received event"); };
raiser.SomeEvent += (sender, e) =>
{
// Bad listener!
Console.WriteLine(" Blocking event");
System.Threading.Thread.Sleep(5000);
Console.WriteLine(" Finished blocking event");
};
// Listener who throws an exception
raiser.SomeEvent += (sender, e) =>
{
Console.WriteLine(" Received event, time to die!");
throw new Exception();
};
// Raise the event, see the effects
raiser.DoSomething();
Console.ReadLine();
}
}
class SomeClass
{
public event EventHandler SomeEvent;
public void DoSomething()
{
OnSomeEvent();
}
private void OnSomeEvent()
{
if (SomeEvent != null)
{
var eventListeners = SomeEvent.GetInvocationList();
Console.WriteLine("Raising Event");
for (int index = 0; index < eventListeners.Count(); index++)
{
var methodToInvoke = (EventHandler)eventListeners[index];
methodToInvoke.BeginInvoke(this, EventArgs.Empty, EndAsyncEvent, null);
}
Console.WriteLine("Done Raising Event");
}
}
private void EndAsyncEvent(IAsyncResult iar)
{
var ar = (System.Runtime.Remoting.Messaging.AsyncResult)iar;
var invokedMethod = (EventHandler)ar.AsyncDelegate;
try
{
invokedMethod.EndInvoke(iar);
}
catch
{
// Handle any exceptions that were thrown by the invoked method
Console.WriteLine("An event listener went kaboom!");
}
}
}
这篇关于如何使异常处理程序异步运行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!