如何在不等待事件侦听器运行的情况下启动事件? [英] How can I fire an event without waiting for the event listeners to run?

查看:133
本文介绍了如何在不等待事件侦听器运行的情况下启动事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个关于.NET(C#)中的事件的问题。我不得不在几个情况下编写代码,其中我有一个后台任务运行,我想通知一个主线程或控制器类,发生了一些事情,如任务完成或完成复制文件,但我不我想要后台任务等待主线程的代理处理事件。



我想做一些像消息传递的事情:发送消息,但谁在乎他们



例如:



几个进程顺序,一个接一个。每个进程需要在后台线程上运行。当工作完成时,事件触发并告诉控制器已完成(假设使用OnCompleted()方法)



问题是如果使用控制器的事件处理程序要启动后续进程,以前的进程的OnComplete方法将保留在调用堆栈上(从不完成执行),直到所有进程完成。



在这种情况下,背景任务如何通过控制器类来完成工作,而不必在堆栈上保持事件提升方法?



示例2: A备份程序。



运行后台线程将每个文件复制到目标。背景需要将UI复制的最后一个文件通知给UI,但不需要等待UI进行更新。相反,它只是想说,BTW,这里有一些信息,现在让我恢复工作。事件侦听器不应该阻止事件提取器的处理。

解决方案

提高事件时可以执行异步调用如上所述),或者只是在后台线程上引发事件:

  void OnUpdated(EventArgs e){
EventHandler h = this.Updated;
if(h!= null)h(e);
}

void DoStuff(){
BigMethod();
ThreadPool.QueueUserWorkItem(OnUpdated,EventArgs.Empty);
BigMethod2();
}

如果您异步提高,多个监听器将同时处理您的事件。至少,这需要一个线程安全的EventArg类。如果您希望他们与您的课程进行交互,那么您应该非常仔细地进行文档编写,也可以使其线程安全。



在后台线程上提升事件同样的注意事项,你的类方法,但你不必担心EventArgs类本身。


I have a question about events in .NET (C#). I have had to write code for several situations in which I have a background task running and I want to notify a main thread, or controller class, that something has occurred, such as task completed, or finished copying a file, but I don't want the background task to wait for the main thread's delegate to process the event.

I want to do something like message passing: Send the message, but who cares what they do with it.

For example:

A class is written to process several processes in sequence, one after the other. Each process needs to run on a background thread. When work is completed, an event fires and tells the controller that it's done (let's say using OnCompleted() method)

The problem is that if the controller's event handler is used to start the subsequent process, the previous processes' OnComplete method stays on the call stack (never finishes executing) until the all of the processes have completed.

In that situation, how could the background task notify the controller class that the work is done without keeping the event raising method on the stack?

Example 2: A backup program.

A background thread runs to copy each file to the destination. The background needs to notify the UI the last file that was copied, but it doesn't need to wait for the UI to update. Instead, it just wants to say, "BTW, here's some info. Now, let me get back to work." The event listener shouldn't block the processing of the event raiser.

解决方案

You could do an async invoke when raising the event (as mentioned), or just raise the event itself on a background thread:

void OnUpdated(EventArgs e) {
   EventHandler h = this.Updated;
   if (h != null) h(e);
}

void DoStuff() {
   BigMethod();
   ThreadPool.QueueUserWorkItem(OnUpdated, EventArgs.Empty);
   BigMethod2();
}

If you raise asynchronously, multiple listeners would be processing your event at the same time. At the very least, that requires a thread-safe EventArg class. If you expect them to interact with your class as well, then you should document very carefully or make it thread-safe as well.

Raising the event on a background thread carries the same caveats for your class methods, but you don't have to worry about the EventArgs class itself.

这篇关于如何在不等待事件侦听器运行的情况下启动事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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