c# - 释放锁并取消一个死锁的 TPL 任务
问题描述
我正在尝试释放 TPL 任务中的锁,该任务卡在对线程不安全的第三方 COM 组件的调用中。
我需要释放锁,因为任务是可排队的(当组件恢复时,它必须可供其他排队的任务使用)
这是代码:
private Task RunQueueableTask()
{
var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromMinutes(5));
var cancellationToken = cancellationTokenSource.Token;
return
Task
.Run(
() =>
{
Monitor.Enter(_lock);
{
try
{
cancellationToken.Register(() =>
{
Monitor.Exit(_lock);
}, true); //"true" ensures that the target syncContext is the active SynchronizationContext.Current
//Blocked thread unsafe third party COM component call
var result = ThirdPartyCOMComponent.Call();
}
finally
{
Monitor.Exit(_lock);
}
}
}, cancellationToken)
.ContinueWith(t =>
{
cancellationTokenSource.Dispose();
});
}
然而,cancellationToken.Register 回调没有被调用,可能是因为它无法获取同步上下文。
现在我正在使用 Monitor.TryEnter 以便后续任务不会被阻止。
private static readonly object _lock = new object();
private Task RunQueueableTask()
{
var cancellationTokenSource = new CancellationTokenSource();
var cancellationToken = cancellationTokenSource.Token;
return
Task
.Run(
() =>
{
if (Monitor.TryEnter(_lock, TimeSpan.FromMinutes(5)))
{
try
{
//Blocked thread unsafe third party COM component call
var result = ThirdPartyCOMComponent.Call();
}
finally
{
Monitor.Exit(_lock);
}
}
else
{
cancellationTokenSource.Cancel();
}
}, cancellationToken)
.ContinueWith(t =>
{
cancellationTokenSource.Dispose();
});
}
专家有什么建议吗?
解决方案
推荐阅读
- macos - 有没有办法不显示 SwiftUI 生命周期 macOS 应用程序的窗口?
- python - 通过 lambda 定义的函数列表的意外行为
- python - 过滤掉前一个条目的 30 个周期内的值
- flutter - 可以在 android 和 ios 的颤振应用程序上删除启动画面
- python - 创建包含 0 或 1 的 N 个元素加起来指定数字 X 的列表
- google-cloud-platform - 使用 org.apache.spark.sql.json 在 Spark sql 中创建临时视图
- blazor - Blazor - 如何为超出该数据类型最大值的值自定义 InputNumber 验证消息?
- python - 使用语音识别库中的监听函数时出错
- python - 即使在四舍五入后也无法获得分类报告
- kubernetes - K8S cert-manager 创建 acme 挑战 pod 时出错