C# 如何改进和/或模块化处理基于事件的任务?
所以我有一个服务器,我通过一个包装好的WebSocket(WebSocket4Net)调用它,我正在构建的库的一个要求是能够等待请求的返回。因此,我有一个MessageEventHandler类,它包含消息传入时由MessageHandler类触发的事件 MessageEventHandler-exC# 如何改进和/或模块化处理基于事件的任务?,c#,events,asynchronous,C#,Events,Asynchronous,所以我有一个服务器,我通过一个包装好的WebSocket(WebSocket4Net)调用它,我正在构建的库的一个要求是能够等待请求的返回。因此,我有一个MessageEventHandler类,它包含消息传入时由MessageHandler类触发的事件 MessageEventHandler-ex public class MessageEventHandler : IMessageEventHandler { public delegate void NodeName
public class MessageEventHandler : IMessageEventHandler
{
public delegate void NodeNameReceived(string name);
public event Interfaces.NodeNameReceived OnNodeNameReceived;
public void NodeNameReceive(string name)
{
if (this.OnNodeNameReceived != null)
{
this.OnNodeNameReceived(name);
}
}
}
public class MessageHandler : IMessageHandler
{
private IMessageEventHandler eventHandler;
public MessageHandler(IMessageEventHandler eventHandler)
{
this.eventHandler = eventHandler;
}
public void ProcessDataCollectorMessage(string message)
{
var serviceMessage = JsonConvert.DeserializeObject<ServiceMessage>(message);
switch (message.MessageType)
{
case MessageType.GetNodeName:
{
var nodeName = serviceMessage.Data as string;
if (nodeName != null)
{
this.eventHandler.NodeNameReceive(nodeName);
}
break;
}
default:
{
throw new NotImplementedException();
}
}
}
MessageHandler示例
public class MessageEventHandler : IMessageEventHandler
{
public delegate void NodeNameReceived(string name);
public event Interfaces.NodeNameReceived OnNodeNameReceived;
public void NodeNameReceive(string name)
{
if (this.OnNodeNameReceived != null)
{
this.OnNodeNameReceived(name);
}
}
}
public class MessageHandler : IMessageHandler
{
private IMessageEventHandler eventHandler;
public MessageHandler(IMessageEventHandler eventHandler)
{
this.eventHandler = eventHandler;
}
public void ProcessDataCollectorMessage(string message)
{
var serviceMessage = JsonConvert.DeserializeObject<ServiceMessage>(message);
switch (message.MessageType)
{
case MessageType.GetNodeName:
{
var nodeName = serviceMessage.Data as string;
if (nodeName != null)
{
this.eventHandler.NodeNameReceive(nodeName);
}
break;
}
default:
{
throw new NotImplementedException();
}
}
}
或
或者,如果我的方法实际上是“好的”,那么有谁能提供一些建议,告诉我如何编写一个助手函数来抽象出以这种方式设置每个函数?任何帮助都将不胜感激。对于初学者,请遵循线程安全模式:
public void NodeNameReceive(string name)
{
var evt = this.OnNodeNameReceived;
if (evt != null)
{
evt (name);
}
}
如果不引用事件对象,则可以在检查null和调用该方法之间将其设置为null。因此我编写了几个类来解决我遇到的问题。第一个是我的CallbackHandle类,它包含TaskCompletionSource中的任务,因此每次在我的示例中发出请求时,都会创建一个新的回调句柄
public class CallbackHandle<T>
{
public CallbackHandle(int timeout)
{
this.TaskCompletionSource = new TaskCompletionSource<T>();
var cts = new CancellationTokenSource(timeout);
cts.Token.Register(
() =>
{
if (this.Cancelled != null)
{
this.Cancelled();
}
});
this.CancellationToken = cts;
}
public event Action Cancelled;
public CancellationTokenSource CancellationToken { get; private set; }
public TaskCompletionSource<T> TaskCompletionSource { get; private set; }
}
公共类回调句柄
{
公共回调句柄(int超时)
{
this.TaskCompletionSource=新的TaskCompletionSource();
var cts=新的CancellationTokenSource(超时);
cts.Token.Register(
() =>
{
如果(this.Cancelled!=null)
{
这个。取消();
}
});
this.CancellationToken=cts;
}
公众活动取消;
public CancellationTokenSource CancellationToken{get;private set;}
public TaskCompletionSource TaskCompletionSource{get;private set;}
}
然后我有一个“处理程序”来管理句柄及其创建
public class CallbackHandler<T>
{
private readonly IList<CallbackHandle<T>> callbackHandles;
private readonly object locker = new object();
public CallbackHandler()
{
this.callbackHandles = new List<CallbackHandle<T>>();
}
public CallbackHandle<T> AddCallback(int timeout)
{
var callback = new CallbackHandle<T>(timeout);
callback.Cancelled += () =>
{
this.callbackHandles.Remove(callback);
callback.TaskCompletionSource.TrySetResult("Error");
};
lock (this.locker)
{
this.callbackHandles.Add(callback);
}
return callback;
}
public void EventTriggered(T eventArgs)
{
lock (this.locker)
{
if (this.callbackHandles.Count > 0)
{
CallbackHandle<T> callback =
this.callbackHandles.First();
if (callback != null)
{
this.callbackHandles.Remove(callback);
callback.TaskCompletionSource.SetResult(eventArgs);
}
}
}
}
}
公共类回调处理程序
{
私有只读IList回调句柄;
私有只读对象锁定器=新对象();
公共回调处理程序()
{
this.callbackHandles=new List();
}
公共CallbackHandle AddCallback(int超时)
{
var callback=新的CallbackHandle(超时);
回调。已取消+=()=>
{
this.callbackHandles.Remove(回调);
callback.TaskCompletionSource.TrySetResult(“错误”);
};
锁(这个柜子)
{
this.callbackHandles.Add(回调);
}
返回回调;
}
已触发公共无效事件(T事件参数)
{
锁(这个柜子)
{
如果(this.callbackHandles.Count>0)
{
回调句柄回调=
this.callbackHandles.First();
if(回调!=null)
{
this.callbackHandles.Remove(回调);
callback.TaskCompletionSource.SetResult(eventArgs);
}
}
}
}
}
这是我实际实现的一个简化版本,但是如果有人需要类似的东西,应该可以开始使用它。因此,在我的示例中,要在我的ClientServiceInterface类上使用它,我首先要创建一个类级处理程序,并像这样使用它:
public class ClientServiceInterface : IClientServiceInterface
{
private readonly CallbackHandler<string> getNodeNameHandler;
public ClientServiceInterface(IMessageEventHandler messageEventHandler, int responseTimeout = 5000)
{
this.messageEventHandler = messageEventHandler;
this.ResponseTimeout = responseTimeout;
this.getNodeNameHandler = new
CallbackHandler<string>();
this.messageEventHandler.OnNodeNameReceived += args => this.getNodeNameHandler.EventTriggered(args);
}
public Task<string> GetNodeNameAsync()
{
CallbackHandle<string> callbackHandle = this.getNodeNameHandler.AddCallback(this.ResponseTimeout);
var serviceMessage = new ServiceMessage
{
Type = MessageType.GetNodeName.ToString()
};
this.ReadyMessage(serviceMessage);
return callbackHandle.TaskCompletionSource.Task;
}
// Rest of class declaration removed for brevity
}
公共类ClientServiceInterface:IClientServiceInterface
{
私有只读回调处理程序getNodeNameHandler;
公共ClientServiceInterface(IMessageEventHandler messageEventHandler,int-responseTimeout=5000)
{
this.messageEventHandler=messageEventHandler;
this.ResponseTimeout=ResponseTimeout;
this.getNodeNameHandler=新建
CallbackHandler();
this.messageEventHandler.OnNodeNameReceived+=args=>this.getNodeNameHandler.EventTriggered(args);
}
公共任务getNodeNameSync()
{
CallbackHandle CallbackHandle=this.getNodeNameHandler.AddCallback(this.ResponseTimeout);
var serviceMessage=新serviceMessage
{
Type=MessageType.GetNodeName.ToString()
};
这是ReadyMessage(serviceMessage);
返回callbackHandle.TaskCompletionSource.Task;
}
//为简洁起见,删除了类的其余部分声明
}
这比我以前拥有的要好看得多(至少在我看来),而且很容易扩展
public class ClientServiceInterface : IClientServiceInterface
{
private readonly CallbackHandler<string> getNodeNameHandler;
public ClientServiceInterface(IMessageEventHandler messageEventHandler, int responseTimeout = 5000)
{
this.messageEventHandler = messageEventHandler;
this.ResponseTimeout = responseTimeout;
this.getNodeNameHandler = new
CallbackHandler<string>();
this.messageEventHandler.OnNodeNameReceived += args => this.getNodeNameHandler.EventTriggered(args);
}
public Task<string> GetNodeNameAsync()
{
CallbackHandle<string> callbackHandle = this.getNodeNameHandler.AddCallback(this.ResponseTimeout);
var serviceMessage = new ServiceMessage
{
Type = MessageType.GetNodeName.ToString()
};
this.ReadyMessage(serviceMessage);
return callbackHandle.TaskCompletionSource.Task;
}
// Rest of class declaration removed for brevity
}