如何在内部死锁的情况下正确取消 Task.Run

How to properly cancel Task.Run with deadlock inside

我有一个事件在调用时会导致死锁,需要进行测试以检查内部是否存在死锁。但是我没有办法影响客户端代码。

我已经尝试过一些技巧,比如

Task t = Task.Run((Action)(() => { while(true); }), cts.Token);

以及在委托中插入令牌的方法,但由于死锁是在委托中调用的 - 任何等待都不会发生。

void Action()
{
    var request = WebRequest.Create(url);(requestUrl);
    request.GetResponse();
    received = instance.RequestReceived;
}

instance.ClientRequeest += (object sender, EventArgs e) => instance.Stop();

我有一个可以订阅的 EventHandler ClientRequest。 还有一个客户端实例,当我试图在它有一些数据要回复时停止它时陷入死锁。

ClientRequest 内部有一个 await - 当被要求停止并有一个请求时 - 陷入无限死锁状态 - 它等待发送请求,并且侦听器已被 Stop 关闭。 在我们的案例中,这是一种可能的情况。但是我似乎没有找到一种方法来调用那个事件而不会使自己在测试中陷入僵局。

因此,如果有一种正确的方法可以让 Instance.ClientRequest 等待几秒钟并抛出异常或被取消或发生其他情况,将非常感谢 - 以避免在实际发生死锁时挂起测试。

如果你有一个 Task,并且你知道它要么在固定时间内完成,要么死锁,你可以:-

var t = Task.Run(() =>
{
    // do something that might deadlock, but if it doesn't will finish for sure in < 1000ms
});

if (!t.Wait(1000))
{
    // He's dead Jim
}