fixed comment into code
This commit is contained in:
@@ -4,14 +4,15 @@ using CursorLang.Interop;
|
||||
namespace CursorLang.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Пускает работать только один экземпляр приложения: повторный запуск не
|
||||
/// поднимает второе окно, а показывает окно уже работающего.
|
||||
/// Lets only one instance of the application run: a second launch does not bring up
|
||||
/// a second window but shows the window of the one already running.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Имена объектов ядра оставлены без префикса Global, то есть живут в пространстве
|
||||
/// имён сеанса. Один экземпляр на всю машину дал бы при быстром переключении
|
||||
/// пользователей странную картину: второй пользователь остался бы без приложения,
|
||||
/// а показать ему окно первого всё равно нельзя — окна принадлежат сеансу.
|
||||
/// The kernel object names are left without the Global prefix, that is, they live in
|
||||
/// the session namespace. A single instance for the whole machine would make for an
|
||||
/// odd picture with fast user switching: the second user would be left without the
|
||||
/// application, and showing them the window of the first one is impossible anyway —
|
||||
/// windows belong to a session.
|
||||
/// </remarks>
|
||||
public sealed class SingleInstanceGate : IDisposable
|
||||
{
|
||||
@@ -29,8 +30,8 @@ public sealed class SingleInstanceGate : IDisposable
|
||||
public event EventHandler? ActivationRequested;
|
||||
|
||||
/// <summary>
|
||||
/// Занимает место единственного экземпляра. Если приложение уже работает,
|
||||
/// просит его показаться и возвращает <c>false</c> — вызвавшему остаётся выйти.
|
||||
/// Takes the single-instance slot. When the application is already running, asks
|
||||
/// it to show itself and returns <c>false</c> — the caller is left to exit.
|
||||
/// </summary>
|
||||
public bool TryAcquire()
|
||||
{
|
||||
@@ -42,15 +43,15 @@ public sealed class SingleInstanceGate : IDisposable
|
||||
}
|
||||
catch (AbandonedMutexException)
|
||||
{
|
||||
// Предыдущий экземпляр завершился аварийно и мьютекс не отпустил.
|
||||
// Владельца у него теперь нет, а значит место свободно
|
||||
// The previous instance crashed and did not release the mutex.
|
||||
// It has no owner now, which means the slot is free
|
||||
_isOwner = true;
|
||||
}
|
||||
|
||||
// Событие открывают оба экземпляра: первый — чтобы ждать просьбы,
|
||||
// второй — чтобы её подать. Кто из них создаст объект, зависит от того,
|
||||
// кто оказался первым, и на работу не влияет
|
||||
_activationRequest = new EventWaitHandle(false, EventResetMode.AutoReset, ActivationEventName);
|
||||
// The event is opened by both instances: the first one to wait for a request,
|
||||
// the second one to make it. Which of them creates the object depends on who
|
||||
// came first and does not affect the work
|
||||
_activationRequest = new EventWaitHandle(false, EventResetMode.AutoReset, _activationEventName);
|
||||
|
||||
if (!_isOwner)
|
||||
{
|
||||
@@ -59,8 +60,8 @@ public sealed class SingleInstanceGate : IDisposable
|
||||
return false;
|
||||
}
|
||||
|
||||
// Ожидание отдано пулу потоков: держать ради него свой поток не за чем,
|
||||
// а просьба может не прийти никогда
|
||||
// The wait is handed over to the thread pool: there is no reason to hold a
|
||||
// thread of our own for it, and the request may never come
|
||||
_activationWait = ThreadPool.RegisterWaitForSingleObject(
|
||||
_activationRequest,
|
||||
OnActivationSignalled,
|
||||
@@ -79,8 +80,8 @@ public sealed class SingleInstanceGate : IDisposable
|
||||
_activationRequest?.Dispose();
|
||||
_activationRequest = null;
|
||||
|
||||
// Мьютекс отпускает тот же поток, что его занял: и то и другое
|
||||
// происходит на потоке пользовательского интерфейса
|
||||
// The mutex is released by the same thread that took it: both happen
|
||||
// on the user interface thread
|
||||
if (_isOwner)
|
||||
{
|
||||
_mutex?.ReleaseMutex();
|
||||
@@ -91,8 +92,8 @@ public sealed class SingleInstanceGate : IDisposable
|
||||
_mutex = null;
|
||||
}
|
||||
|
||||
// Пул потоков сообщает о просьбе где придётся, а окно слушается только
|
||||
// своего потока
|
||||
// The thread pool reports the request from wherever it happens to be, while the
|
||||
// window obeys only its own thread
|
||||
private void OnActivationSignalled(object? state, bool timedOut) =>
|
||||
_dispatcher.BeginInvoke(() => ActivationRequested?.Invoke(this, EventArgs.Empty));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user