Se stai cercando di mantenere l'interfaccia utente sensibile in attesa che il semaforo qui, potrebbe avere senso, ma c'è un problema: "Semaphores don't have owners". Se si condivide il semaforo tra due processi e l'altro si blocca senza chiamare Semaphore.Release()
, , la proprietà sulla risorsa condivisa verrà persa. Il processo rimanente potrebbe non essere in grado di acquisirlo di nuovo.
IMO, la semantica Mutex
sarebbe più appropriata qui, ma con Mutex
avresti bisogno di affinità di thread. Forse, è possibile acquisire il mutex, accedere alla risorsa e rilasciarlo sullo stesso thread:
await Task.Factory.StartNew(() =>
{
mutex.WaitOne();
try
{
// use the shared resource
}
finally
{
mutex.ReleaseMutex();
}
}, TaskCreationOptions.LongRunnning);
Se questo non è possibile (ad esempio, perché è necessario accedere alla risorsa condivisa sul thread dell'interfaccia utente principale), si potrebbe usa un thread dedicato per il mutex. Questo può essere fatto con uno schedulatore di attività personalizzato, ad es. di StaTaskScheduler
con numberOfThreads:1
Stephen Toub (il filo di supporto non deve essere fatta STA in questo caso):
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();
}
}
Aggiornato, se siete preoccupati per WinRT (vale a dire, .NET for Windows Store Apps) o Windows Phone, quindi Task.Factory.StartNew
w/TaskCreationOptions.LongRunning
è ancora lì, è possibile utilizzarlo al posto di new Thread()
con StaTaskScheduler
o qualcosa come il mio ThreadWithSerialSyncContext
ogni volta che è necessario un thread in background con affinità.
Non c'è tecnicamente alcun problema a fare questo. Se si dovrebbe fare questo o meno dipende da molti più dettagli non specificati nel tuo post. –
L'operazione sottostante è intrinsecamente asincrona, eppure si sta eseguendo un thread del thread thread in modo asincrono sull'operazione asincrona in modo che sia possibile indicare in modo asincrono quando si è finito. Questo è generalmente di scarsa progettazione e dovrebbe essere evitato se possibile. È un segno che probabilmente non dovresti usare "Semaphore" in primo luogo. – Servy
Indica un errore da parte dell'utente o un design discutibile. Sospetto che il primo - tu dici che "devi fare la sincronizzazione tra processi" ma questo non sincronizzerà nulla. Se il processo che chiama 'WaitOne' in realtà ha bisogno di sapere quando viene segnalato il semaforo, perché non attende in modo sincrono? Se non ha bisogno di sapere, perché avere il semaforo? –