Dan*_*ant 6 .net parallel-processing deadlock task task-parallel-library
我想开始使用任务并行库,因为这是执行异步操作的推荐框架.我无法找到的一件事是强制中止的任何方法,例如Thread.Abort提供的内容.
我特别关注的是我安排运行代码的任务,我不希望完全信任.特别是,我不能确定这个不受信任的代码不会死锁,因此我无法确定使用此代码的任务我是否会完成.我想远离真正的AppDomain隔离(由于编组的开销和复杂性),但我也不想让任务线程挂起,死锁.有没有办法在TPL中做到这一点?
这样做的方法是使用CancellationToken和新的取消模型.新的取消模型以几种类型集成到.NET Framework中.最重要的是System.Threading.Tasks,System.Threading.Tasks.Task,System.Threading.Tasks.Task和System.Linq.ParallelEnumerable.
这是你的问题的一个例子.此代码将始终死锁,因为调用代码首先获取锁定,然后死锁任务尝试获取相同的锁定.
public void Example()
{
object sync = new Object();
lock (sync)
{
CancellationTokenSource canceller = new CancellationTokenSource();
ManualResetEvent started = new ManualResetEvent(false);
Task deadlocked = Task.Factory.StartNew(() =>
{
started.Set();
// EVIL CODE: This will ALWAYS deadlock
lock(sync) { };
},
canceller.Token);
// Make sure task has started.
started.WaitOne();
canceller.Cancel();
try
{
// Wait for task to cancel.
deadlocked.Wait();
}
catch (AggregateException ex)
{
// Ignore canceled exception. SIMPLIFIED!
if (!(ex.InnerException is TaskCanceledException))
throw;
}
}
}
Run Code Online (Sandbox Code Playgroud)
TPL中的任务取消是合作的.换句话说,这将永远是死锁,因为没有处理取消令牌被设置为取消,因为任务线程被锁定.
有一种解决方法,但仍然依赖于不受信任的代码的作者做正确的事情:
public static void Example2()
{
Mutex sync = new Mutex(true);
CancellationTokenSource canceller = new CancellationTokenSource();
bool started = false;
Task deadlocked = Task.Factory.StartNew(() =>
{
started = true;
// EVIL CODE: This will ALWAYS deadlock
WaitHandle.WaitAny(new WaitHandle[] { canceller.Token.WaitHandle, sync });
},
canceller.Token);
// Make sure task has started.
while (!started) { }
canceller.Cancel();
try
{
// Wait for task to cancel.
deadlocked.Wait();
}
catch (AggregateException ex)
{
// Ignore canceled exception. SIMPLIFIED!
if (!(ex.InnerException is TaskCanceledException))
throw;
}
}
Run Code Online (Sandbox Code Playgroud)
注意事项; 取消是合作的.您可以使用Token.WaitHandle获取句柄并与其他同步原语的句柄一起等待它.互斥体比监视器(或锁定)慢得多.
真的,如果你不相信代码的作者足以让他们实现合作取消,那么我会质疑让他们在同一个线程的AppDomain中运行的完整性.
有关详细信息,请参阅
http://msdn.microsoft.com/en-us/library/dd997364.aspx
http://msdn.microsoft.com/en-us/library/dd537607.aspx
http://msdn.microsoft.com/en-us/library/ee191552.aspx
| 归档时间: |
|
| 查看次数: |
5035 次 |
| 最近记录: |