加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 创建一个异步方法,包装订阅并在总线上发布

发布时间:2020-12-15 23:42:20 所属栏目:百科 来源:网络整理
导读:我有一种实现此接口的总线: public interface IBus{ void PublishT(T t); void SubscribeT(Guid subscriptionId,ActionT action); void UnsubscribeT(Guid subscriptionId);} 以下是我如何使用它的示例: public void PrintName(){ IBus bus = new Bus(); v
我有一种实现此接口的总线:

public interface IBus
{
    void Publish<T>(T t);
    void Subscribe<T>(Guid subscriptionId,Action<T> action);
    void Unsubscribe<T>(Guid subscriptionId);
}

以下是我如何使用它的示例:

public void PrintName()
{
    IBus bus = new Bus();
    var id = Guid.NewGuid();
    bus.Subscribe<ReplyUserName>(id,replyUserName =>
    {
        bus.Unsubscribe<ReplyUserName>(id);
        Console.WriteLine(replyUserName.UserName);
    });

    Bus.Publish(new RequestUserName());
}

这里是RequestUserName和ReplyUserName类:

public class RequestUserName {}

public class ReplyUserName
{
    public string UserName { get; set; }
}

但是我想写一个扩展方法,用异步包装它:

public static class BusExtension
{
    public static async Task<TResult> Request<TRequest,TResult>(this IBus bus,TRequest request)
    {
        // TODO...
    }
}

这样我就能用这样的方式编写前面的代码:

public async void PrintName()
{
    IBus bus = new Bus();
    var replyUserName = await bus.Request<RequestUserName,ReplyUserName>(new RequestUserName());
    Console.WriteLine(replyUserName.UserName);
}

我该怎么写而不是TODO?

解决方法

您可以使用TaskCompletionSource< T>到 wrap anything成为await兼容的方法.

public static Task<TResult> Request<TRequest,TRequest request)
{
  var tcs = new TaskCompletionSource<TResult>();
  var id = Guid.NewGuid();
  bus.Subscribe<TResult>(id,result =>
  {
    bus.Unsubscribe<TResult>(id);
    tcs.TrySetResult(result);
  });
  bus.Publish(request);
  return tcs.Task;
}

但是请注意,您应该是ensure that the task is completed.如果总线有可能不响应请求,您应该有一个计时器或某些错误TaskCompletionSource.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读