Как использовать WaitHandler.WaitAll в MSTest без предупреждений STA? - PullRequest
8 голосов
/ 14 июля 2010

Существует ли способ модульного тестирования WaitHandle.WaitAll() при использовании встроенного в Visual Studio решения для модульного тестирования.Когда я пытаюсь запустить тест, который использует эту функцию в Visual Studio, тест не пройден, и при проверке результатов теста отображается следующая ошибка:

WaitAll for multiple handles on a STA thread is not supported

Я хотел бы иметь возможность провести модульное тестирование использованияWaitAll(), поскольку все большее количество кодовой базы моего API теперь переходит к шаблону IAsyncResult, в отличие от других средств выполнения многопоточных операций.

Редактировать

Основываясь на предложении Энтони, вот простой вспомогательный метод, который можно использовать для вызова такого кода в среде модульного тестирования:

public static void TestInMTAThread(ThreadStart info)
{
    Thread t = new Thread(info);
    t.SetApartmentState(ApartmentState.MTA);
    t.Start();
    t.Join();
}

Ответы [ 4 ]

7 голосов
/ 14 июля 2010

У вас могут быть две проблемы.Первый - тот, который вы указали: вы не можете ожидать несколько дескрипторов ожидания в потоке STA (состояние квартиры потока MSTest).Мы можем исправить это с помощью потока MTA, созданного вручную.

public static void OnMtaThread(Action action)
{
    var thread = new Thread(new ThreadStart(action));
    thread.SetApartmentState(ApartmentState.MTA);
    thread.Start();
    thread.Join();
}

В среде также установлен максимальный предел ожидания .В .NET 2.0 он, похоже, жестко запрограммирован на 64. Ожидание больше, чем предел, даст NotSupportedException.Вы можете использовать метод extension для ожидания на всех дескрипторах ожидания в чанках.

public static void WaitAll<T>(this List<T> list, TimeSpan timeout)
    where T : WaitHandle
{
    var position = 0;
    while (position <= list.Count)
    {
        var chunk = list.Skip(position).Take(MaxWaitHandles);
        WaitHandle.WaitAll(chunk.ToArray(), timeout);
        position += MaxWaitHandles;
    }
}

И вы бы смонтировали их вместе, как показано в тесте (в части Act или Assertтест)

OnMtaThread(() => handles.WaitAll(Timespan.FromSeconds(10)));
2 голосов
/ 23 мая 2012

В Visual Studio 2008 & 2010 вы можете изменить файл .testsettings для запуска тестов в потоке MTA, добавив <ExecutionThread apartmentState="MTA" />.

<Execution>
     <ExecutionThread apartmentState="MTA" />
</Execution>
0 голосов
/ 04 июня 2014

Для VS2008 инструкции немного отличаются от VS2010.Для VS2008 отредактируйте файл testrunconfig и добавьте следующее в элемент TestRunConfiguration:

<ExecutionThread apartmentState="MTA" />
0 голосов
/ 28 августа 2012

Для моей Visual Studio 2010 тесты работают только в следующей конфигурации.

<Execution>
     <ExecutionThread apartmentState="1" />
</Execution>
...