Есть ли метод waiteone, который по существу, призывает сброс сначала?

StackOverflow https://stackoverflow.com/questions/4109395

Вопрос

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

Решение состоит в том, чтобы вызвать сброс прямо перед Waitone. Есть ли более чистое решение или это единственный способ сделать это? Пример кода:

private void DoSomeWork()
{
    Thread thrd = new Thread(new ThreadStart(DoSomeOtherStuff));
    thrd.Start();

    //mEvt.Reset();
    mEvt.WaitOne();

    //continue with other stuff
}

private void DoSomeOtherStuff()
{
    /* lots of stuff */

    mEvt.Set();
}

private void ExceptionTriggerNeedsToBreakOutOfDoSomeWork()
{
   mEvt.Set();
}

После того, как исключение обрабатывается, мне нужно снова вызвать домосочную работу, но поскольку набор, возможно, были вызваны несколькими исключениями (или исключениями Rethrown), в режиме ожидания ожидается.

Мое решение - всегда вызовите сброс перед вайкой. Является ли это сосредоточенное решение, плохой дизайн или есть другой тип события, который будет справиться с этим сценарием?

РЕДАКТИРОВАТЬ: Я только что переместил закомментированный сброс (предложенное решение) рядом с событием.

Это было полезно?

Решение

Моя проблема заключалась в том, что если вы вызовите сброс () перед вайкой (), у вас проблемы, если нет набора (). Это может произойти, если вы вызовите SET (), затем нажмите RESET () сразу после этого перед ударом WaiteNe (). Даже если вы вызовите набор () дважды, нет никакой гарантии, вы не будете вызывать сброс () после обоих, блокируя резьбу без механизма для выпуска.

В идеале, у вас будет попробовать ...CATCA .. Блок. Это работает для вас?

Ганс верен, что в этом сценарии многопоточное чтение не нужно. Мои проблемы применяются только в том случае, если вы действительно многопоточно с вашими звонками в Waitone ().

Это также касается меня, что вы звоните более одного раза ... это означает, что при названии первого набора ресурс должен действительно оставаться заблокированным? Если вы все еще можете ударить SET () во второй раз, мне говорят, что вы все еще выполняете код, который работает с общими ресурсами. В этом случае вы не хотите позвонить в Waitone (), чтобы разблокировать.

Также обратите внимание, от MSDN:

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

В любом случае, похоже, ваш код должен либо пойти по маршруту выбрасывать исключение или запустить до завершения, но не оба. Т.е. вы не должны звонить () дважды.

Другие советы

Это не реальная проблема, вызов Waitone () автоматически сбрасывает событие. В конце концов, вы использовали AutoResetEvent, а не ручное. Ключевая фраза здесь - автоматический сброс.

Видя, что он прорядет прямо через важно (), тоже довольно нормально. У вас есть хороший Core Core CPU, нить началась прямо сейчас, когда вы звоните, и вы не взяли, кроме нескольких микросекунд, чтобы получить работу. Миллисекунды, что быстрее, быстрее мгновение ока.

Возможно, больше до такой степени, что вам просто не нужна нить здесь. Начало один, потом жду его до конца бессмысленно. Просто позвоните в Dosomeothestuff () напрямую.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top