有没有办法指定处理已注册事件代理的订单或优先级?例如,我有一个事件,我想在任何其他事件之前立即处理,但我希望允许其他对象注册该事件的监听器。如何实现这一目标?
让我们说proc1总是在proc 2之前运行。
class MessageProcessor
{
private DataClient Client;
public MessageProcesser(DataClient dc)
{
Client = dc;
Client.MessageReceived += ProcessMessage;
}
void proc1(MessageEventArgs e)
{
// Process Message
}
}
class DataClient
{
public event MessageReceievedHandler MessageReceived;
}
void main()
{
DataClient dc = new DataClient();
MessageProcessor syncProcessor = new MessageProcessor(dc); // This one is high priority and needs to process all sync immediately when they arrive before any data messages
MessageProcessor dataProcessor= new MessageProcessor(dc); // This one can process the data as it has time when sync messages are not being processed.
// do other stuff
}
这样做的原因是,我有一台服务器通过UDP流发送消息。它将在数据突发之前发送同步消息。我意识到两个处理程序都会在收到同步消息时触发,但为了减少延迟,我希望syncProcessor对象在dataProcessor事件之前处理事件。这样可以减少正在处理的同步消息的延迟。
此外,我团队中的其他人可能也想要注册事件来处理特定消息。他们可能有自己的对象来注册事件(可能不是MessageProcessor),即使Sync消息仍然应该具有尽可能低的延迟。
编辑通过更好的示例使目标更加清晰。
答案 0 :(得分:5)
当您多次订阅某个事件时,在事件被触发时,无法确定处理程序的执行顺序。
根据this answer,订阅订单中的订单,但正如作者所说,这是一个实施细节,您不能依赖它。
您当然可以编写自己的“事件管理器”(请参阅下面的脏示例),以已知的顺序执行处理程序,但我认为这不是一个好主意。也许您应该重新设计您的活动以取消您的要求。
public class MyClass
{
// Could be anything...
public delegate void MyEventHandler(object sender, EventArgs e);
public event MyEventHandler TestEvent;
public void Test()
{
if (this.TestEvent != null)
{
this.TestEvent(this, EventArgs.Empty);
}
}
}
public class EventManager
{
private List<EventHandler> Handlers = new List<EventHandler>();
public void AddHandler(EventHandler handler)
{
this.Handlers.Add(handler);
}
public void RemoveHandler(EventHandler handler)
{
this.Handlers.Remove(handler);
}
public void Handler(object sender, EventArgs e)
{
foreach (var z in this.Handlers)
{
z.Invoke(sender, e);
}
}
}
private static void Main(string[] args)
{
MyClass test = new MyClass();
EventManager eventManager = new EventManager();
// Subscribes to the event
test.TestEvent += eventManager.Handler;
// Adds two handlers in a known order
eventManager.AddHandler(Handler1);
eventManager.AddHandler(Handler2);
test.Test();
Console.ReadKey();
}
private static void Handler1(object sender, EventArgs e)
{
Console.WriteLine("1");
}
private static void Handler2(object sender, EventArgs e)
{
Console.WriteLine("2");
}
答案 1 :(得分:1)
在这种情况下,最好只在第一个事件结束时调用第二个事件,等等。
答案 2 :(得分:0)
在您的示例中,因为调用无效,所以在proc1结束时不运行proc2?
答案 3 :(得分:0)
如果这是您自己定义的事件,那么您最好的选择是将其扩展为具有BeforeMessageReceived,MessageReceived和AfterMessageReceived事件。 (好吧,所以也许MessageProcessed会是一个更好的根,因为你可以在收到消息之前知道)。
这将使您更好地控制不同事件处理程序的确切位置。
在,事件,之后模式之后,您会看到相同的。