gpt4 book ai didi

c# - 创建一个在总线上包装订阅和发布的异步方法

转载 作者:行者123 更新时间:2023-11-30 13:31:24 24 4
gpt4 key购买 nike

我有一种实现这个接口(interface)的总线:

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, TResult>(this IBus bus, 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 出错的东西。 .

关于c# - 创建一个在总线上包装订阅和发布的异步方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21798009/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com