我有一个 .Net 的Windows服务(客户端),它正在与 SignalR Hub(服务器)通信。大多数客户端方法需要一些时间才能完成。当从服务器接收到调用时,如何包装目标方法/hub.On以避免警告:
"因为未等待此调用,所以在调用完成之前,当前方法的执行将继续进行。请考虑对调用结果应用 await 运算符"
以下是客户端的启动/设置代码示例:
IHubProxy _hub
string hubUrl = @"http://localhost/";
var connection = new HubConnection(hubUrl, hubParams);
_hub = connection.CreateHubProxy("MyHub");
await connection.Start();
_hub.On<Message>("SendMessageToClient", i => OnMessageFromServer(i.Id, i.Message));
_hub.On<Command>("SendCommandToClient", i => OnCommandFromServer(i.Id, i.Command));
此外,在客户端上,这是一些方法的示例:
public static async Task<bool> OnMessageFromServer(string Id, string message)
{
try
{
var result = await processMessage(message); //long running task
}
catch (Exception ex)
{
throw new Exception("There was an error processing the message: ", ex);
}
return result;
}
public static async Task<bool> OnCommandFromServer(string Id, string command)
{
try
{
var result = await processCommand(command); //long running task
}
catch (Exception ex)
{
throw new Exception("There was an error processing the message: ", ex);
}
return result;
}
最终,我认为_hub.On是注册回调函数,而不是来自服务器的实际执行(调用)。 我认为我需要介入实际执行的中间过程,在等待On [X] FromServer的结果后返回结果。
************* 带有更正代码的更新示例*********************
IHubProxy _hub
string hubUrl = @"http://localhost/";
var connection = new HubConnection(hubUrl, hubParams);
_hub = connection.CreateHubProxy("MyHub");
await connection.Start();
//original
//_hub.On<Message>("SendMessageToClient", i => OnMessageFromServer(i.Id, i.Message));
//_hub.On<Command>("SendCommandToClient", i => OnCommandFromServer(i.Id, i.Command));
//new async
_hub.On<Message>("SendMessageToClient",
async (i) => await OnMessageFromServer(i.Id, i.Message));
_hub.On<Message>("SendCommandToClient",
async (i) => await OnCommandFromServer(i.Id, i.Message));
//expanding to multiple parameters
_hub.On<Message, List<Message>, bool, int>("SendComplexParamsToClient",
async (p1, p2, p3, p4) =>
await OnComplexParamsFromServer(p1.Id, p1.Message, p2, p3, p4));
然后目标方法的签名将类似于
public static async Task<bool> OnComplexParamsFromServer(string id, string message,
List<Message> incommingMessages, bool eatMessages, int repeat)
{
try
{
var result = await processCommand(message); //long running task
if (result)
{
// eat up your incoming parameters
}
}
catch (Exception ex)
{
throw new Exception("There was an error processing the message: ", ex);
}
return result;
}
感谢@AgentFire的迅速回复!!!
.Wait();
,而是使用await connection.Start()
。 - AgentFire