2

委托执行期间的上下文切换是否可以切换执行线程?

我在 LinqPad 中尝试了这个片段几次,但它没有上new Exception()线,这似乎表明它将在原始线程上继续,但也许我这里的小测试不足以测试这个,我只是不确定。

void Main()
{
    var list = Enumerable.Range(1,100000);
    list.AsParallel().ForAll( i=>
    {
        var threadId = System.Threading.Thread.CurrentThread.ManagedThreadId;
        System.Threading.Thread.Sleep(0); // allow a context switch
        work(i,threadId); 
    });
    "Complete".Dump();
}

void work(int num,int threadId)
{
    var currentId = System.Threading.Thread.CurrentThread.ManagedThreadId;
    if(threadId!=currentId)
    {
        throw new Exception();
    }
}
4

2 回答 2

3

当一个任务被调度时,它将永远永远使用分配给它的第一个线程。该线程可能会停止运行并让另一个线程(来自线程池或不来自线程池)做一些工作,并且整个进程可能会停止以让另一个进程做一些工作,但无论如何你总是会回到线程中你开始了。

于 2012-04-11T19:14:37.207 回答
2

不——相同的方法不能在一个线程中开始执行并在另一个线程中结束。想想看——每个线程都有自己的堆栈,如果可能的话,每个上下文切换都会复制堆栈。

在您的示例中,上下文切换时间片将提供给另一个线程,但它将执行另一个代码。另一个代码可能在同一个方法中,但调用堆栈会是其他的,threadiId也会是其他的。

所以你永远不会看到你的例外。

于 2012-04-11T19:19:34.723 回答