我正在创建消息传递系统,但遇到了问题。我需要发布一条消息并等待响应,然后再返回发布函数。

这就是我的功能

public async Task<bool> Publish(int ClientId, string msg){
    ...
    // Wait and check if the client the message was sent to respond
    // if that does not happen within 5 seconds, return false, else true
}

private async Task MessageIntercept(int ClientId, string msg){
    // Intercepts all messages
    ...
}


这两个功能都在服务器上,并且每当发送一条消息(包括使用Publish方法发送的一条消息)时,MessageIntercept任务就会自动运行。我可以通过调用上面提到的服务器项目的“发布”功能从asp.net网站项目发送消息。

基本上,我想要执行的操作是调用bool Success = Publish(1,"This is a test")并能够确定邮件是否已成功发送,客户端可以在5秒钟内理解并恢复该邮件。

这是逐步发生的事情:


我使用Publish从服务器向设备发送消息
消息被MessageIntercept方法拦截(我并不真正在意,但是代码被编写为可以拦截所有消息)
客户端接收并处理消息
客户端响应,并且消息在MessageIntercept中被拦截,这是我想在返回Publish方法之前验证消息的位置


示例消息;

服务器消息:

{
    ClientId: 13,
    msg: "Hello World"
}


客户回应:

{
    ClientId: 13,
    msg: "{Success: true}"
}


MessageIntercept拦截所有消息,包括刚刚发送的请求,由于它是请求而不是响应,因此应忽略。但是,一旦客户端响应消息,我想告诉Publish方法响应已成功完成,然后返回true。否则,如果客户端在5秒内未响应,则应假定为false。

最佳答案

没有等待发布的内容,因此您需要添加一个通知挂钩。像“ OnMessageIntercept”这样的事件对我来说很有意义。

然后,您可以等待将通过调用通知挂钩完成的任务。

public async Task<bool> PublishAsync(int clientId, string msg)
{
    // Wait and check if the client the message was sent to respond
    // if that does not happen within 5 seconds, return false, else true
    var messageRecievedSource = new TaskCompletionSource<int>();
    void intercept(object sender, MessageInterceptEventArgs args)
    {
        if (args.ClientId == clientId)
            messageRecievedSource.SetResult(clientId);
    }
    OnMessageIntercept += intercept;
    // EDIT
    // var completed = Task.WaitAny(Task.Delay(TimeSpan.FromSeconds(5)), messageRecievedSource.Task) > 0;
    var completed = await Task.WhenAny(Task.Delay(TimeSpan.FromSeconds(5)), messageRecievedSource.Task);
    OnMessageIntercept -= intercept;

    // EDIT
    // return completed;
    return completed == messageRecievedSource.Task;
}

event EventHandler<MessageInterceptEventArgs> OnMessageIntercept;

private async Task MessageIntercept(int clientId, string msg)
{
    OnMessageIntercept?.Invoke(this, new MessageInterceptEventArgs(clientId, msg));
    // Intercepts all messages
}

class MessageInterceptEventArgs
{
    public MessageInterceptEventArgs(int clientId, string msg)
    {
        ClientId = clientId;
        Msg = msg ?? throw new ArgumentNullException(nameof(msg));
    }

    public int ClientId { get; }
    public string Msg { get; }
}

关于c# - 等待异步功能,然后返回,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59374266/

10-11 02:24