Что это за необычный код в ThreadPool?


Я использовал Reflector для просмотра некоторых исходных текстов для .NET ThreadPool, когда он показал следующее:

private static bool QueueUserWorkItemHelper(WaitCallback callBack, object state, ref StackCrawlMark stackMark, bool compressStack)
{
    bool flag = true;
    if (callBack == null)
    {
        throw new ArgumentNullException("WaitCallback");
    }
    EnsureVMInitialized();
    if (ThreadPoolGlobals.useNewWorkerPool)
    {
        try
        {
            return flag;
        }
        finally
        {
            QueueUserWorkItemCallback callback = new QueueUserWorkItemCallback(callBack, state, compressStack, ref stackMark);
            ThreadPoolGlobals.workQueue.Enqueue(callback, true);
            flag = true;
        }
    }
    // code below here removed
}

Блок try/finally поразил меня как очень однотипный C#. Зачем так писать? Какая разница, если вы избавились от try / finally и перенесли возврат в конец?

Я понимаю, как работает рефлектор и что это может быть не исходный источник. Если вы думаете, что это так, Можете ли вы предположить, каким мог быть первоначальный источник?
2 3

2 ответа:

На самом деле, этот пустой блок try и код в шаблоне finally block описаны в книге Джеффри Рихтера "CLR через C#". Дело в том, что если что-то пойдет не так и поток будет прерван, то блоки finally гарантированно выполнятся. По крайней мере, они скорее выполнят, чем попробуют блоки. Более подробно вы можете посмотреть в разделе упомянутой книги, который описывает исключения и обработку ошибок

Microsoft опубликовала исходный код в .NET-хотя я все еще использую Reflector из-за более удобного просмотра. Это фактический фрагмент кода из .NET 4.0.

// 
// If we are able to create the workitem, we need to get it in the queue without being interrupted 
// by a ThreadAbortException.
// 
try { }
finally
{
    QueueUserWorkItemCallback tpcallBack = new QueueUserWorkItemCallback(callBack, state, compressStack, ref stackMark);
    ThreadPoolGlobals.workQueue.Enqueue(tpcallBack, true);
    success = true;
}