Wenn Sie versuchen, die Benutzeroberfläche, die auf zu halten, während hier für die Semaphore warten, könnte es Sinn machen, aber es gibt einen Haken: "Semaphores don't have owners". Wenn Sie den Semaphor zwischen zwei Prozessen freigeben und der andere Prozess abstürzt, ohne Semaphore.Release()
, aufzurufen, geht die Eigentumsrechte an der freigegebenen Ressource verloren. Der verbleibende Prozess ist möglicherweise nicht in der Lage, es erneut zu erfassen.
IMO, die Mutex
Semantik wäre hier angemessener, aber mit Mutex
würden Sie Thread-Affinität benötigen. Vielleicht können Sie die Mutex erwerben, auf die Ressource zugreifen und sie auf dem gleichen Thread Mitteilung:
await Task.Factory.StartNew(() =>
{
mutex.WaitOne();
try
{
// use the shared resource
}
finally
{
mutex.ReleaseMutex();
}
}, TaskCreationOptions.LongRunnning);
Wenn das nicht möglich ist (zB weil Sie die gemeinsam genutzte Ressource auf dem Haupt-UI-Thread zugreifen müssen), könnten Sie Verwenden Sie einen dedizierten Thread für den Mutex. Dies kann mit einem benutzerdefinierten Aufgabenplaner, z.B. Stephen Toub der StaTaskScheduler
mit numberOfThreads:1
(der Helfer-Thread muss nicht STA in diesem Fall gemacht werden):
using (var scheduler = new StaTaskScheduler(numberOfThreads: 1))
{
await Task.Factory.StartNew(
() => mutex.WaitOne(),
CancellationToken.None,
TaskCreationOptions.None,
scheduler);
try
{
// use the shared resource on the UI thread
}
finally
{
Task.Factory.StartNew(
() => mutex.ReleaseMutex(),
CancellationToken.None,
TaskCreationOptions.None,
scheduler).Wait();
}
}
aktualisiert, wenn Sie über WinRT betroffen sind (dh .NET for Windows Store Apps) oder Windows Phone, dann Task.Factory.StartNew
w/TaskCreationOptions.LongRunning
ist immer noch da, Sie können es anstelle von new Thread()
mit StaTaskScheduler
oder etwas wie meine ThreadWithSerialSyncContext
verwenden, wenn Sie einen Hintergrund-Thread mit Affinität benötigen.
Es ist technisch kein Problem, dies zu tun. Ob Sie dies tun sollten oder nicht, hängt von vielen weiteren Details ab, die in Ihrem Post nicht angegeben sind. –
Die zugrunde liegende Operation ist inhärent asynchron, und dennoch wartet ein Threadpool-Thread synchron auf den asynchronen Vorgang, sodass Sie asynchron angeben können, wann Sie fertig sind. Dies ist im Allgemeinen ein schlechtes Design und sollte wenn möglich vermieden werden. Es ist ein Zeichen, dass Sie "Semaphore" wahrscheinlich nicht verwenden sollten. – Servy
Dies deutet entweder auf einen Fehler oder auf ein fragwürdiges Design hin. Ich vermute, dass Ersteres - Sie sagen, Sie müssen "Cross-Prozess-Synchronisation" tun, aber das wird nicht wirklich etwas synchronisieren. Wenn der Prozess, der 'WaitOne' aufruft, tatsächlich wissen muss, wann der Semaphor signalisiert wird, warum wartet er nicht synchron? Wenn es nicht wissen muss, warum überhaupt das Semaphor? –