??????????ò??е???????????е??????????????????????????????????Ч????????????????????????????????????????????????????????????λ?????TestRunner??

var executorWrapper=newExcetorWrapper(assemblyName??null??false);

var testRunner=newTestRunner(executorWrapper??newRunnerLoggerWrapper());

testRunner.RunAssembly();

???е?RunnerLoggerWrapper??????????????????Xunit??IRunnerLogger??XUnit????ò?????????????????????????

?????????????λ?????????????????????????????????????е???????????????У???????????????????г????в??????????????д????????????

privatestaticManualResetEvent[] resetEvents;

privatestaticQueueassemblyQue;

privatestaticreadonlyObject LockAssembly2Queue=newObject();

publicvoidRun()

{

for(var index=0; index

{

resetEvents[index]=newManualResetEvent(false);

ThreadPool.QueueUserWorkItem(DoWork?? index);

}

WaitForAllManualEvent();

}

privatevoidWaitForAllManualEvent()

{

if(Thread.CurrentThread.ApartmentState=ApartmentState.STA)

{

foreach(var manualResetEventinresetEvents)

{

    WaitHandle.WaitAny(newWaitHandle[]{manualResetEvent});

}

}

else

{

WaitHandle.WaitAll(resetEvents);

}

}

privatestaticvoidDoWork(Object index)

{

Thread.CurrentThread.ApartmentState=ApartmentState.STA;

while(true)

{

stringcurrentAssemblyName=null;

lock(LockAssembly2Queue)

{

    if(assemblyQue.Count!=0)

    {

        currentAssemblyName=assemblyQue.Dequeue();

    }

    else

    {

        resetEvents[(int)index].Set();

        Console.WriteLine("Exited current thread:{0}"?? Thread.CurrentThread.Name);

        break;

        }

}

if(currentAssemblyName!=null)

{

    newTestRunnerWrapperWithAssembly(currentAssemblyName).Runner();

}

}

}