我正在用C#编写一个程序,它将从其他程序中读取消息,它需要读取消息,并在某些情况下准备和发送响应。
我编写了这个方法来处理单个消息,我将其异步调用(使用await
)或同步调用它,具体取决于其类型。
public async void HandleMessage(Message message)
{
IEnumerable<Tuple<Message, ulong>> responses;
try
{
if (!_communicateTypesToHandleSync.Contains(message.GetType()))
{
responses = await Task.Run(() => _requestHandler.HandleRequest(message));
}
else
{
responses = _requestHandler.HandleRequest(message);
}
foreach (var response in responses)
{
CSMessageHandler.AddMessageToSend(response.Item1, response.Item2);
}
}
catch (Exception ex)
{
_logger.Error(ex, "Error while handling message");
}
}
问题是使用await调用HandleRequest
似乎总是返回一个空集合(我用条件断点检查它)。
我试图调试它,当我终于发现发生了什么时,我在HandleRequest
的末尾设置了一个断点,只有当集合不为空时才会停止。在此断点处,代码执行已停止,当我从HandleRequest
退出时,即使在HandleMessage
我也没有空responses
。
答案 0 :(得分:2)
如果无效,则HandleMessage应返回 Task
Task<IEnumerable<Tuple<Message, ulong>>>
如果您想返回IEnumerable<Tuple<Message, ulong>>
。除非是代表,否则不应使用void。
您的代码应为
public async Task<IEnumerable<Tuple<Message, ulong>>> HandleMessage(Message message)
{
IEnumerable<Tuple<Message, ulong>> responses;
try
{
if (!_communicateTypesToHandleSync.Contains(message.GetType()))
{
responses = await Task.Run(() => _requestHandler.HandleRequest(message));
}
else
{
responses = _requestHandler.HandleRequest(message);
}
foreach (var response in responses)
{
CSMessageHandler.AddMessageToSend(response.Item1, response.Item2);
}
return responses;
}
catch (Exception ex)
{
_logger.Error(ex, "Error while handling message");
}
}
你的电话应该是
await HandleMessage(Message message);
由于该方法无效,因此当您调用 HandleMessage 时,无法等待。该方法在1个线程上输入,然后执行 Task.Run 以启动另一个线程。当第二个线程启动时,线程1被释放并继续在调用函数上运行。
例如:
//do one thing
HandleMessage(message);
//Do other work
当 Task.Run 旋转另一个线程时,线程1将在释放时继续执行其他工作。