有没有大神知道为什么会这样, 有没有别的办法达到这个效果吗
把GetString方法改成这样好像也能达到预期, 但是不知道有没有Bug会不会很耗性能, 其实我更想知道的是前面为什么会报错, 以及解决办法
public async Task<string> GetString()
{
while (!source.IsCancellationRequested)
{
await Task.Delay(1 * 1000);
}
//await Task.Delay(10 * 1000, source.Token);
return "";
}
Task.Delay中传CancellationToken就是会抛异常,要想不抛异常用Task.WhenAny和TaskCompletionSource的组合即可。
static TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>(); string GetB() { tcs.SetCanceled(); return ""; } async Task<string> GetString() { await Task.WhenAny(Task.Delay(3000), tcs.Task); return ""; }
厉害了, 这个就是我想要的
2次请求不是同一个Controller实例
CancellationTokenSource source 是一个静态对象的
ManualResetEvent
AutoResetEvent
Monitor
不建议你这样做,如果在你的场景下b不调用你那服务,那服务最后会因为资源耗尽跪掉
应该是a发消息过来然后就返回,b后面一旦给你了相关联的请求后再回调a
其实我也不想这么弄的, 客户端b 其实也是一台服务器
当收到客户端a 的请求后, 服务器需要向b 发送一个请求, 然后 b 收到请求后, 在异步向我们服务器发送一个请求, 当收到b 的请求后, 我们服务器需要把b 的返回值返回给 客户端 a
这个主要是服务器b 就是一个奇葩, 他们不能同步的返回消息,
然后客户端 a 也是一个奇葩, 两分钟请求一次我们不能主动通知他, 又必须马上获得结果
@Mirck: 真心建议你们这个玩意再考虑下,不然到时候出了问题谁背锅?
如果你非要按照你的逻辑来掰的话是有点麻烦的,你需要一个有key为包含发送给b的请求标识,value为类似ManualResetEvent(太重)或者ManualResetEventSlim的玩意来进行控制。
如果你的服务是个集群的话就更麻烦点,需要找个缓存啥的做个分布式锁(确保在收到b的响应式请求前处理a请求的继续阻塞住)