微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

释放锁并取消一个死锁的 TPL 任务

如何解决释放锁并取消一个死锁的 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();
            });
}

然而,可能因为它无法获取syncContext,所以没有调用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();
            });
}

专家有什么建议吗?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。