Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用EventHandler在C中处理多个发布服务器_C#_.net_Event Handling_Publish Subscribe - Fatal编程技术网

C# 使用EventHandler在C中处理多个发布服务器

C# 使用EventHandler在C中处理多个发布服务器,c#,.net,event-handling,publish-subscribe,C#,.net,Event Handling,Publish Subscribe,我目前正在尝试学习一些关于C语言中事件处理的知识,我正在测试这些东西,我已经创建了这个小测试程序 public class Message : EventArgs { public string message { get; set; } public Message(String message){ this.message = message; } } public class Component { public event Even

我目前正在尝试学习一些关于C语言中事件处理的知识,我正在测试这些东西,我已经创建了这个小测试程序

public class Message : EventArgs {

    public string message { get; set; }
    public Message(String message){
        this.message = message;
    }

}

public class Component {

    public event EventHandler<Message> onComponentEvent;
    public string uuid;
    public Component () {
        Guid g = Guid.NewGuid();
        uuid = g.ToString();
    }
    public void update () {
        Task.Factory.StartNew (() => componentEvent (uuid)); 
    }
    private void componentEvent (string message) {
        onComponentEvent?.Invoke(this, new Message(message));
    }
}

public class Entity {
    List<Component> components;
    public EventHandler<Message> EntityEvent;
    public Entity () {
        components = new List<Component>();
    }

    public void addComponent () {
        var c = new Component();
        c.onComponentEvent += ComponentEvents;
        this.components.Add (c);
    }

    public void update () {
        System.Console.WriteLine("I am an entity and I am updating");
        foreach (Component c in this.components) {
            c.update ();
        }
    }

    private void ToManagerEvent (String message) {
        EntityEvent?.Invoke(this, new Message(message));
    }

    private void ComponentEvents (object source, Message e) {
        Task.Factory.StartNew ( () => ToManagerEvent ( e.message ));
    }

}

public class Manager {
    List<Entity> entities;
    public EventHandler<Message> ManagerEvent;
    public Manager () {
        this.entities = new List<Entity>();
    }

    public void addEntity (Entity e) {
        e.EntityEvent += EntityEvents;
        this.entities.Add(e);
    }

    public void update () {
        foreach ( Entity e in entities ) {
            e.update ();
        }   
    }
    private void ToGameManagerEvent (Message message) {
        ManagerEvent?.Invoke(this, message);
    }    
    private void EntityEvents (object source, Message e) {
        System.Console.WriteLine(e.message);
        Task.Factory.StartNew ( () => ToGameManagerEvent (e));
    }
}

public class GameManager {
    ConcurrentQueue<Entity> queue;
    Manager manager;
    public GameManager () {
        this.queue = new ConcurrentQueue<Entity>();
        this.manager = new Manager();
        this.manager.ManagerEvent += ManagerEvents;
        Entity e1 = new Entity();
        e1.addComponent();
        this.manager.addEntity(e1);
    }

    public void update () {
        while (this.queue.TryDequeue(out Entity en)){
            manager.addEntity(en);
        }
        System.Console.WriteLine("begin update");
        manager.update();
    }

    private void ManagerEvents (object source, Message e) {
        queue.Enqueue (new Entity());
    }
}    
class Program
{

    static void Main(string[] args)
    {

        GameManager gm = new GameManager();
        //1
        gm.update();
        System.Threading.Thread.Sleep(500);
        //2
        gm.update();
        System.Threading.Thread.Sleep(500);
        //4
        gm.update();
        System.Threading.Thread.Sleep(500);
        //8
        gm.update();
        System.Threading.Thread.Sleep(500);

    }
}
简言之,这个程序应该有一个更新循环,每个更新组件都会触发一个事件,从组件->实体->管理器->游戏管理器中弹出。其中,Gamemanager然后在队列中添加一个新实体,并在每次管理器更新之前尝试退出队列并将其添加到管理器实体列表中

预期行为=>每次更新都会使实体数量加倍。 行为发生=>只有一个组件触发一个冒泡事件,每次更新只产生一个新实体


因此,当同时订阅多个发布服务器时会出现问题吗?我认为这是一个基本的问题,我对此有误解,所以任何指向我做错了什么的指针都是非常受欢迎的。

您的代码中的问题是:

private void ManagerEvents (object source, Message e) {
    queue.Enqueue (new Entity());
}
private void ManagerEvents (object source, Message e) {
    Entity e1 = new Entity();
    e1.addComponent();
    queue.Enqueue (e1);
}
您只是添加了一个普通实体。没有组件触发事件

你应该做的是:

private void ManagerEvents (object source, Message e) {
    queue.Enqueue (new Entity());
}
private void ManagerEvents (object source, Message e) {
    Entity e1 = new Entity();
    e1.addComponent();
    queue.Enqueue (e1);
}
现在您得到了我认为您期望的输出:

begin update I am an entity and I am updating fdc40694-fcf9-4f49-b2b1-29ff9735214f begin update I am an entity and I am updating I am an entity and I am updating fdc40694-fcf9-4f49-b2b1-29ff9735214f a05b42fa-5c77-4d4c-a59c-b7f85bdcf1cc begin update I am an entity and I am updating I am an entity and I am updating I am an entity and I am updating I am an entity and I am updating fdc40694-fcf9-4f49-b2b1-29ff9735214f a05b42fa-5c77-4d4c-a59c-b7f85bdcf1cc 6dfd20ed-72c5-4fde-b41f-0fa250d3b760 d343a7b3-a7e1-4785-8bd7-1df3cb947255 begin update I am an entity and I am updating I am an entity and I am updating I am an entity and I am updating I am an entity and I am updating I am an entity and I am updating a05b42fa-5c77-4d4c-a59c-b7f85bdcf1cc fdc40694-fcf9-4f49-b2b1-29ff9735214f 1b02458c-e015-4cb8-81d6-26e8f94821fc d343a7b3-a7e1-4785-8bd7-1df3cb947255 6dfd20ed-72c5-4fde-b41f-0fa250d3b760 I am an entity and I am updating I am an entity and I am updating I am an entity and I am updating 1b06f9fd-1f94-4db0-a6ff-7574c833af9c 2cb02ff4-eb18-4024-92cf-1d098bde476a 5b674091-2f8f-4613-9aba-274aee938e94 我还对您的代码做了一些更新,使其更符合常规的命名约定,等等

试试这个:

public class MessageEventArgs : EventArgs
{
    public string Message { get; private set; }

    public MessageEventArgs(string message)
    {
        this.Message = message;
    }
}

public class Component
{
    public event EventHandler<MessageEventArgs> ComponentEvent;
    public string Uuid { get; private set; }

    public Component()
    {
        this.Uuid = Guid.NewGuid().ToString();
    }

    public async Task UpdateAsync()
    {
        Console.WriteLine("      Component.UpdateAsync() - Begin");
        await this.OnComponentEventAsync(this.Uuid);
        Console.WriteLine("      Component.UpdateAsync() - End");
    }

    protected virtual void OnComponentEvent(string message)
    {
        this.ComponentEvent?.Invoke(this, new MessageEventArgs(message));
    }

    protected virtual Task OnComponentEventAsync(string message)
    {
        return Task.Factory.StartNew(() => this.OnComponentEvent(message));
    }
}

public class Entity
{
    private List<Component> _components;
    public EventHandler<MessageEventArgs> EntityEvent;

    public Entity()
    {
        _components = new List<Component>();
    }

    public void AddComponent()
    {
        var c = new Component();
        c.ComponentEvent += this.ComponentEvent;
        _components.Add(c);
    }

    public async Task UpdateAsync()
    {
        Console.WriteLine("    Entity.UpdateAsync() - Begin");
        foreach (Component c in _components)
        {
            await c.UpdateAsync();
        }
        Console.WriteLine("    Entity.UpdateAsync() - End");
    }

    protected virtual void OnEntityEvent(string message)
    {
        this.EntityEvent?.Invoke(this, new MessageEventArgs(message));
    }

    protected virtual Task OnEntityEventAsync(string message)
    {
        return Task.Factory.StartNew(() => this.OnEntityEvent(message));
    }

    private async void ComponentEvent(object source, MessageEventArgs e)
    {
        await this.OnEntityEventAsync(e.Message);
    }
}

public class Manager
{
    private List<Entity> _entities;
    public event EventHandler<MessageEventArgs> ManagerEvent;

    public Manager()
    {
        _entities = new List<Entity>();
    }

    public void AddEntity(Entity e)
    {
        e.EntityEvent += this.EntityEvent;
        _entities.Add(e);
    }

    public async Task UpdateAsync()
    {
        Console.WriteLine("  Manager.UpdateAsync() - Begin");
        foreach (var e in _entities)
        {
            await e.UpdateAsync();
        }
        Console.WriteLine("  Manager.UpdateAsync() - End");
    }

    protected virtual void OnManagerEvent(string message)
    {
        this.ManagerEvent?.Invoke(this, new MessageEventArgs(message));
    }

    protected virtual Task OnManagerEventAsync(string message)
    {
        return Task.Factory.StartNew(() => this.OnManagerEvent(message));
    }

    private async void EntityEvent(object source, MessageEventArgs e)
    {
        System.Console.WriteLine(e.Message);
        await this.OnManagerEventAsync(e.Message);
    }
}

public class GameManager
{
    private ConcurrentQueue<Entity> _queue = new ConcurrentQueue<Entity>();
    private Manager _manager = new Manager();

    public GameManager()
    {
        _manager.ManagerEvent += this.ManagerEvent;

        var entity = new Entity();
        entity.AddComponent();
        _manager.AddEntity(entity);
    }

    public async Task UpdateAsync()
    {
        Console.WriteLine("");
        Console.WriteLine("GameManager.UpdateAsync() - Begin");
        while (_queue.TryDequeue(out var entity))
        {
            _manager.AddEntity(entity);
        }
        await _manager.UpdateAsync();
        Console.WriteLine("GameManager.UpdateAsync() - End");
        Console.WriteLine("");
    }

    private void ManagerEvent(object source, MessageEventArgs e)
    {
        var entity = new Entity();
        entity.AddComponent();
        _queue.Enqueue(entity);
    }
}

class Program
{
    static async Task Main(string[] args)
    {
        var gm = new GameManager();
        //1
        await gm.UpdateAsync();
        await Task.Delay(TimeSpan.FromSeconds(0.5));
        //2
        await gm.UpdateAsync();
        await Task.Delay(TimeSpan.FromSeconds(0.5));
        //4
        await gm.UpdateAsync();
        await Task.Delay(TimeSpan.FromSeconds(0.5));
        //8
        await gm.UpdateAsync();
        await Task.Delay(TimeSpan.FromSeconds(0.5));
    }
}

您需要学习c命名约定。为了符合标识符的正常命名,您的代码有很多问题。这里还有很多代码似乎是不必要的。当你的问题是关于C语言中的事件时,你的任务、队列等都在进行中。请修正你的问题,使其包含一个可靠地再现你所问问题的好问题。还要详细解释您已经做了哪些工作,以便尝试调试问题并找出发生了什么,以及您需要帮助的具体内容。Stack Overflow不是一个合适的论坛,你可以找人指导你学习语言特性。