【问题标题】:How to properly cancel Task.Run with deadlock inside如何正确取消 Task.Run 内部有死锁
【发布时间】:2019-08-08 12:42:51
【问题描述】:

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

我已经尝试了几种技巧,例如

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

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

【问题讨论】:

  • 如果客户端代码部分完成,是否中止或安全取消/回滚? (如果您只是中止一侧,甚至可能客户端代码将完全完成)。

标签: c# lambda delegates .net-standard


【解决方案1】:

如果你有一个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
}

【讨论】:

    猜你喜欢
    • 2019-10-22
    • 2020-09-20
    • 2019-01-27
    • 1970-01-01
    • 2021-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-23
    相关资源
    最近更新 更多