Подтвердить что ты не робот

Запустите новый процесс, который выполняет делегат

Возможно ли в .NET выполнить метод (делегировать, статический метод, что угодно) в дочернем процессе? System.Diagnostics.Process похоже, требует фактического имени файла, что означает, что требуется отдельный исполняемый файл.

То, что я пытаюсь сделать, - проверить в unit test, что ресурс ОС очищается при завершении процесса. Я знаю, что для создания такой сборки и ее выполнения можно использовать генерацию CodeDOM или IL, но вся цель модульных тестов заключается в том, чтобы изолировать составные части, а не создавать сложность. По этой же причине я хотел бы избежать отдельной сборки вообще.

В идеале я бы сделал что-то вроде:

public static void CreateCounter()
{
    var counter = new PerformanceCounter("category", "counter", "instance");
    counter.InstanceLifetime = PerformanceCounterInstanceLifetime.Process;
}

[Test]
public void TestResourceDisposal()
{
    // Start child process to execute CreateCounter()
    ...
    // verify the resource is disposed
}
4b9b3361

Ответ 1

Прежде всего, нет, нет способа сделать это. я процесс подразумевает .exe. Это не Unix, где вы можете развить процесс, который является копией родителя.

Я просто создаю маленький .exe для запуска. Вам нужно запустить тест с разными счетчиками производительности? Если он работает с одним, то, безусловно, он будет работать с любым из них?

Ответ 2

То, о чем вы говорите, это не unit test. Взаимодействие с фактическими (дорогостоящими) службами операционной системы нарушает основной принцип изоляции, к которому стремятся единичные тесты.

Если вы намерены тестировать код более подробно, на самом деле взаимодействуя с счетчиком производительности и т.д., это будет интеграционный тест и должен быть написан в более "сверхмощный" способ, т.е. записывать отдельный EXE при необходимости, выполнять любые сложные шаги настройки или очистки и т.д.

Если вам нужно unit test компоненты, имеющие отношение к счетчику производительности, вы должны сначала абстрагировать эту зависимость. Как правило, вы должны создать базовый класс или интерфейс, представляющий площадь поверхности счетчика производительности, а затем создать тестовый двойной, чтобы заменить его функциональность на (тест). Реальная система будет использовать простую оболочку, которая делегирует фактический счетчик производительности и будет выполняться интеграционными тестами, как указано выше.

Из чтения вашего комментария выше, это почти похоже на то, что вы пытаетесь проверить гарантию платформы .NET. Я бы поставил под сомнение, действительно ли это необходимо, поскольку он уже достаточно хорошо протестирован, хотя, возможно, вы хотите проверить, что ваш код правильно его использует (в этом случае вы можете либо выполнить тестирование единицы или интеграции в зависимости от проверки, которую вы ищете).

Ответ 3

Я не уверен точно, что вы пытаетесь выполнить, но было бы проще вернуть экземпляр счетчика производительности из CreateCounter и использовать директиву using, поскольку PerformanceCounter IDisposable. Вот так:

using (var counter = CreateCounter())
{
     // Do some work
}

Затем счетчик всегда будет очищен, даже если вы выбросите его во время теста.

В противном случае я думаю, что вы хотите создать новый поток. Затем вы можете thread.Join() ждать завершения потока. Дополнительную информацию см. В пространстве имен System.Threading.