我有以下循环通知某个事件的观察者列表:
foreach (var observer in registeredObservers)
{
if (observer != null)
{
observer.OnMessageRecieveEvent(new ObserverEvent(item));
}
}
有没有办法可以使用TPL立即通知所有已注册的观察员?
以下是OnMessageRecieveEvent()
中执行的代码 public void OnMessageRecieveEvent(ObserverEvent e)
{
SendSignal(e.message.payload);
}
private void SendSignal(Byte[] signal)
{
if (state.WorkSocket.Connected)
{
try
{
// Sends async
state.WorkSocket.BeginSend(signal, 0, signal.Length, 0, new AsyncCallback(SendCallback), state.WorkSocket);
}
catch (Exception e)
{
log.Error("Transmission Failier for ip: " + state.WorkSocket.AddressFamily , e);
}
}
else
{
CloseConnection();
}
}
所以我的问题是:
我该怎么做:
我真的想这样做吗?这会对表现有益吗?
答案 0 :(得分:3)
由于循环的所有单次迭代都是启动异步套接字操作(这本身非常快),因此您很可能无法并行化代码。< / p>
答案 1 :(得分:1)
您的foreach
循环写为Parallel.ForEach
。约。
Parallel.ForEach(registeredObservers, (obs, item) =>
{
if (obs != null)
obs.OnMessageReceivedEvent(new ObserverEvent(item));
});
答案 2 :(得分:1)
您可以尝试使用TaskCompletionSource
或Task.FromAsync
方法将SendSignal
方法转换为Task
方法。然后,您可以创建一个任务列表,并在启动所有通知后等待结果。
代码可能看起来像这样(未经测试和未编译):
public async Task NotifyObservers()
{
List<Task> notifyTasks = new List<Task>();
foreach (var observer in registeredObservers)
{
if (observer != null)
{
notifyTasks.Add(observer.OnMessageRecieveEvent(new ObserverEvent(item)));
}
}
// asynchronously wait for all the tasks to complete
await Task.WhenAll(notifyTasks);
}
public async Task OnMessageRecieveEvent(ObserverEvent e)
{
await SendSignal(e.message.payload);
}
private Task SendSignal(Byte[] signal)
{
if (!state.WorkSocket.Connected)
{
CloseConnection();
return Task.FromResult<object>(null);
}
else
{
var tcs = new TaskCompletionSource<object>();
try
{
// Sends async
state.WorkSocket.BeginSend(signal, 0, signal.Length, 0, (ar) =>
{
try
{
var socket = (Scoket)ar.AsyncState;
tcs.SetResult(socket.EndSend(ar));
}
catch(Exception ex)
{
tcs.SetException(ex);
}
}
, state.WorkSocket);
}
catch (Exception e)
{
log.Error("Transmission Failier for ip: " + state.WorkSocket.AddressFamily , e);
tcs.SetException(e);
}
}
return tcs.Task;
}