C# 事件优先级和进程顺序

C# 事件优先级和进程顺序,c#,.net,events,C#,.net,Events,是否有方法指定处理已注册事件委托的顺序或优先级?例如,我希望在任何其他事件之前立即处理一个事件,但我希望允许其他对象也将侦听器注册到该事件。如何做到这一点 假设我希望proc1总是在proc2之前运行 class MessageProcessor { private DataClient Client; public MessageProcesser(DataClient dc) { Client = dc; Client.Messag

是否有方法指定处理已注册事件委托的顺序或优先级?例如,我希望在任何其他事件之前立即处理一个事件,但我希望允许其他对象也将侦听器注册到该事件。如何做到这一点

假设我希望proc1总是在proc2之前运行

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流发送消息的服务器。它将在数据突发之前发送同步消息。我意识到当接收到同步消息时,这两个处理程序都会启动,但为了减少延迟,我希望在dataProcessor事件之前处理syncProcessor对象事件。这将减少正在处理的同步消息的延迟

此外,我的团队中的其他人可能也希望注册事件以处理特定消息。他们可能有自己的对象来注册事件(可能不是MessageProcessor),即使同步消息应该具有尽可能低的延迟


编辑通过一个更好的例子使目标更加明确。

我要冒险说不。AFAIK事件本质上是异步发送的。因此,将按照其绑定的顺序发送。但是,结果可能会以不同的顺序返回。唯一的方法是在第一个事件的回调中调度第二个事件。这不是特定于语言的,只是更多关于事件的体系结构


在您的示例中,由于调用是无效的,因此在proc1结束时不运行proc2?

在这种情况下,您最好在第一个事件结束时调用第二个事件,以此类推。

如果这是您自己定义的事件,那么您最好扩展它以接收BeforeMessageReceived,MessageReceived和AfterMessageReceived事件。(好的,也许MessageProcessed是一个更好的根,因为您可以在收到消息之前就知道)

这将使您能够更精确地控制不同事件处理程序发生的位置


您可以在事件前后看到相同的模式。

当您多次订阅事件时,无法确定触发事件时处理程序的执行顺序

根据,订阅顺序中的顺序,但正如文章作者所说,这是一个实现细节,您不能依赖它

当然,您可以编写自己的“事件管理器”(参见下面的脏示例),以已知顺序执行处理程序,但我认为这不是一个好主意。也许你应该重新设计你的活动来删除你的需求

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");
}
公共类MyClass
{    
//可能是任何东西。。。
公共委托void MyEventHandler(对象发送方,事件参数e);
公共事件MyEventHandler TestEvent;
公开无效测试()
{
如果(this.TestEvent!=null)
{
this.TestEvent(this,EventArgs.Empty);
}
}
}
公共类事件管理器
{
私有列表处理程序=新列表();
public void AddHandler(EventHandler处理程序)
{
this.Handlers.Add(handler);
}
公共void RemoveHandler(EventHandler)
{
this.Handlers.Remove(handler);
}
公共无效处理程序(对象发送方、事件参数)
{
foreach(此.Handlers中的var z)
{
z、 调用(发送方,e);
}
}
}
私有静态void Main(字符串[]args)
{
MyClass测试=新的MyClass();
EventManager EventManager=新的EventManager();
//订阅该活动
test.TestEvent+=eventManager.Handler;
//按已知顺序添加两个处理程序
AddHandler(Handler1);
AddHandler(Handler2);
test.test();
Console.ReadKey();
}
私有静态void Handler1(对象发送方,事件参数e)
{
控制台。写入线(“1”);
}
私有静态void Handler2(对象发送方,事件参数e)
{
控制台。写入线(“2”);
}

将处理程序中的MessageEventArgs排队,然后启动一个实现优先级和依赖性的方法。这是一个错误,你知道,在我尝试不经常失败之前,我会与自己进行激烈的对话。我举这个例子只是为了简单,因为我意识到在这个例子中,在同一个资源/对象中注册两个事件是没有意义的。我将改变我的设置,以更准确地表示我的目标。@Tony:这个主意很有趣。我同意这可能会进入一个问题领域。我实际上在考虑创建一个接口,当有人注册一个事件时,DataClient会注册它,但有一个优先级映射对象,当收到消息时,它会按照定义的顺序调用处理程序中的事件。但这似乎也是一条不好的道路。@galford13x,这是可行的,也是有问题的。在我看来,你正试图将多事件处理程序模型转变为一组协作过程,这充其量只是一个预兆,更糟糕的是,它将变得非常脆弱。+1:这个例子与我计划做的类似。但我也认为这是一条不好的道路。我的目标是在.net中内置一个解决方案。事件是异步调度的吗?我认为它们都在同一个线程上调度,这当然会使它们同步。我想你的意思是他们没有明确的顺序?如果它们总是按照绑定的顺序进行调度,那么我可以通过确保首先注册最高优先级的事件来实现我的目标?那么你是说当一个事件被调度时整个线程都处于休眠状态?如果事件不受任何约束怎么办。应用程序将无限期地等待。这就是为什么我认为在这一点上是异步的?否?如果需要同步发生,则应该从函数1调用函数2,其中函数1是事件处理程序。否则,您将创建竞赛条件。这就是世界上所有其他事件模型的存在方式。我99%肯定它在C#中的工作原理,我不说第