Действительно ли использованием является Взаимное исключение, чтобы препятствовать тому, чтобы несколько экземпляров той же программы работали безопасный?

Если вы переключитесь на TemplateField, вы можете сделать это встроенным.

<asp:TemplateField HeaderText="BankAcc">
    <ItemTemplate>
        <%# string.IsNullOrEmpty(Eval("HiddenBankAcc").ToString()) ? Eval("FullBankAcc") : Eval("HiddenBankAcc")%>
    </ItemTemplate>
</asp:TemplateField>

Или как логическое значение

<asp:TemplateField HeaderText="BankAcc">
    <ItemTemplate>
        <%# Convert.ToBoolean(Eval("FullBankAcc")) ? Eval("FullBankAcc") : Eval("HiddenBankAcc")%>
    </ItemTemplate>
</asp:TemplateField>
45
задан Blorgbeard 19 August 2013 в 22:22
поделиться

7 ответов

В целом да это будет работать. Однако дьявол находится в деталях.

Во-первых Вы хотите закрыть взаимное исключение в finally блок. Иначе Ваш процесс мог резко завершить и оставить его в сообщенном состоянии, как исключение. Это сделало бы его так, чтобы будущие экземпляры процесса не были в состоянии запустить.

, К сожалению, хотя, даже с finally блок необходимо иметь дело с потенциалом, что процесс будет завершен, не освобождая взаимное исключение. Это может произойти, например, если пользователь уничтожает процесс через TaskManager. Существует состояние состязания в Вашем коде, который позволил бы, чтобы второй процесс добрался AbandonedMutexException в эти WaitOne вызов. Вам будет нужна стратегия восстановления этого.

я поощряю Вас читать на детали Взаимоисключающего класса . Используя его не всегда просто.

<час>

Подробно останавливающийся на возможности состояния состязания:

следующая последовательность событий может произойти, который заставил бы второй экземпляр приложения бросать:

  1. Нормальный запуск процесса.
  2. 118-секундный процесс запускает и aquires дескриптор к взаимному исключению, но выключается перед эти WaitOne вызов.
  3. Процесс № 1 резко завершается. Взаимное исключение не уничтожается, потому что процесс № 2 имеет дескриптор. Это вместо этого установлено на заброшенное состояние.
  4. второй процесс начинает работать снова и добирается AbanonedMutexException.
42
ответ дан the Tin Man 26 November 2019 в 20:55
поделиться

Это более обычно и удобно использовать события Windows с этой целью. Например,

static EventWaitHandle s_event ;

bool created ;
s_event = new EventWaitHandle (false, 
    EventResetMode.ManualReset, "my program#startup", out created) ;
if (created) Launch () ;
else         Exit   () ;

, Когда Ваш процесс выходит или завершается, Windows закроет событие для Вас и уничтожит его, если никакие открытые дескрипторы не останутся.

Добавленный : для управления сессиями используйте Local\ и Global\ префиксы для события (или взаимное исключение) имя. Если Ваше приложение в расчете на пользователя, просто добавьте имя соответственно искаженного зарегистрированного пользователя к имени события.

61
ответ дан Anton Tykhyy 26 November 2019 в 20:55
поделиться

Можно использовать взаимное исключение, но сначала удостовериться, что это действительно, что Вы хотите.

, поскольку "предотвращение нескольких экземпляров" ясно не определяется. Это может означать

  1. Предотвращение нескольких экземпляров, запущенных на том же сеансе пользователя, неважно, сколько рабочих столов, которые сеанс пользователя имеет, но позволяющий несколько экземпляров работать одновременно за различными сеансами пользователя.
  2. Предотвращение нескольких экземпляров, запущенных в том же рабочем столе, но разрешении нескольких экземпляров работать, пока, каждый находится в отдельном рабочем столе.
  3. Предотвращение нескольких экземпляров, запущенных для той же учетной записи пользователя, неважно, сколько рабочих столов или сессий, работающих в соответствии с этой учетной записью, существует, но позволяющий несколько экземпляров работать одновременно за сессиями, работающими под другой учетной записью пользователя.
  4. Предотвращение нескольких экземпляров, запущенных на той же машине. Это означает, что, неважно, сколько рабочих столов используется произвольным числом пользователей, может быть самое большее один экземпляр выполнения программы.

При помощи взаимного исключения, Вы в основном используете определить номер 4.

11
ответ дан Stefan 26 November 2019 в 20:55
поделиться

В Windows, завершая процесс имеет следующие результаты:

  • Любые остающиеся потоки в процессе отмечены для завершения.
  • Любые ресурсы, выделенные процессом, освобождены.
  • Все объекты ядра закрываются.
  • код процесса удален из памяти.
  • код выхода процесса установлен.
  • объект процесса сообщен.

Взаимоисключающие объекты являются объектами ядра, таким образом, любой сохраненный процессом закрывается, когда процесс завершается (в Windows так или иначе).

, Но, отметьте следующий бит в CreateMutex () документы:

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

3
ответ дан Michael Burr 26 November 2019 в 20:55
поделиться

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

using( Mutex mutex = new Mutex( false, "mutex name" ) )
{
    if( !mutex.WaitOne( 0, true ) )
    {
        MessageBox.Show("Unable to run multiple instances of this program.",
                        "Error",  
                        MessageBoxButtons.OK, 
                        MessageBoxIcon.Error);
    }
    else
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new MainForm());                  
    }
}
2
ответ дан slavoo 26 November 2019 в 20:55
поделиться

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

Один протест состоит в том, что основанный на взаимном исключении подход не позволяет Вам активировать первую инстанцию приложения, когда пользователь пытается запустить второй экземпляр.

альтернатива к PInvoke к FindWindow, сопровождаемому SetForegroundWindow на первой инстанции. Другая альтернатива должна проверить на Ваш процесс по имени:

Process[] processes = Process.GetProcessesByName("MyApp");
if (processes.Length != 1)
{
    return;
} 

Обе из этих последних альтернатив имеют гипотетическое состояние состязания, где два экземпляра приложения могли быть запущены одновременно и затем обнаружить друг друга. Это вряд ли произойдет на практике - на самом деле, во время тестирования, я не мог заставить его произойти.

Другая проблема с этими двумя последними альтернативами - то, что они не будут работать при использовании Служб удаленных рабочих столов.

0
ответ дан RoadWarrior 26 November 2019 в 20:55
поделиться

Я использую этот метод, я считаю, что он быть в безопасности, потому что мьютекс уничтожается, если он долго не удерживается каким-либо приложением (и приложения завершаются, если они не могут изначально создать мьютекст). Это может или не может работать идентично в «процессах AppDomain» (см. Ссылку внизу):

// Make sure that appMutex has the lifetime of the code to guard --
// you must keep it from being collected (and the finalizer called, which
// will release the mutex, which is not good here!).
// You can also poke the mutex later.
Mutex appMutex;

// In some startup/initialization code
bool createdNew;
appMutex = new Mutex(true, "mutexname", out createdNew);
if (!createdNew) {
  // The mutex already existed - exit application.
  // Windows will release the resources for the process and the
  // mutex will go away when no process has it open.
  // Processes are much more cleaned-up after than threads :)
} else {
  // win \o/
}

Вышесказанное страдает от примечаний в других ответах / комментариях о том, что вредоносные программы могут сидеть на мьютексе. Здесь не проблема. Кроме того, мьютекс без префикса создается в «локальном» пространстве. Наверное, здесь все правильно.

См .: http://ayende.com/Blog/archive/2008/02/28/The-mysterious-life-of-mutexes.aspx - поставляется с Джоном Скитом; -)

10
ответ дан 26 November 2019 в 20:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: