【发布时间】:2020-04-07 22:34:32
【问题描述】:
我目前正在尝试学习一些关于 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);
}
}
简而言之,这个程序应该有一个更新循环,其中每次更新一个组件都会触发一个事件,该事件从Component -> Entity -> Manager -> GameManager 冒泡。然后Gamemanager 在队列中添加一个新的Entity 并尝试在每个经理更新之前将其出列并添加到managers entity 列表中。
预期行为 => 每次更新都会使实体数量翻倍。 发生的行为 => 只有一个组件会触发一个事件,该事件会导致每次更新仅产生 1 个新实体。
因此同时订阅多个发布者时会出现问题吗?我假设我对此有一些基本的误解,因此非常欢迎任何指出我做错了什么的指针。
【问题讨论】:
-
您需要学习 c# 命名约定。为了符合标识符的正常命名,您的代码存在大量问题。
-
这里还有很多代码似乎没有必要。当您的问题是 C# 中的 关于 事件时,您有任务、队列等正在进行。请解决您的问题,以便它包含一个好的minimal reproducible example,它可以可靠地重现您所询问的问题。还要详细解释您已经完成的工作,以便尝试调试问题并弄清楚发生了什么,以及具体是什么您需要帮助。 Stack Overflow 不适合让某人在语言功能方面为您提供辅导。
标签: c# .net event-handling publish-subscribe