Jeśli próbujesz utrzymać UI reaguje czekając na semaforze tutaj, to może mieć sens, ale jest pewien haczyk: "Semaphores don't have owners". Jeśli udostępnisz semafor między dwoma procesami, a inny proces zawiesza się bez wywoływania Semaphore.Release()
, prawa własności do zasobu udostępnionego zostaną utracone. Pozostały proces może nie być w stanie go odzyskać.
IMO, semantyczne Mutex
byłoby bardziej odpowiednie tutaj, ale z Mutex
potrzebujesz powinowactwa wątku. Być może, można nabyć mutex, dostęp do zasobów i zwolnić go w tym samym wątku:
await Task.Factory.StartNew(() =>
{
mutex.WaitOne();
try
{
// use the shared resource
}
finally
{
mutex.ReleaseMutex();
}
}, TaskCreationOptions.LongRunnning);
Jeśli nie jest to możliwe (na przykład dlatego, że trzeba uzyskać dostęp do zasobu udostępnionego na głównym wątku UI), można użyj dedykowanego wątku dla muteksa. Można to zrobić za pomocą niestandardowego programu do planowania zadań, np. Stephen Toub na StaTaskScheduler
z numberOfThreads:1
(gwint pomocnik nie musi być w tym przypadku STA):
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();
}
}
Updated, jeśli jesteś zaniepokojony WinRT (tj .NET for Windows Store Apps) lub Windows Phone, a następnie Task.Factory.StartNew
w/TaskCreationOptions.LongRunning
nadal tam jest, możesz go używać zamiast new Thread()
z StaTaskScheduler
lub coś podobnego do mojego ThreadWithSerialSyncContext
, gdy potrzebujesz gwintu tła z powinowactwem.
Technicznie nie ma problemu z robieniem tego. To, czy powinieneś to zrobić, zależy od wielu innych szczegółów, które nie są określone w twoim poście. –
Podstawowa operacja jest z natury asynchroniczna, a mimo to wątek puli wątków synchronicznie czeka na działanie asynchroniczne, aby można asynchronicznie wskazać, kiedy skończysz. Jest to generalnie kiepski projekt i należy go w miarę możliwości unikać. To znak, że prawdopodobnie nie powinieneś używać "Semafora" w pierwszej kolejności. – Servy
Wskazuje to na błąd z Twojej strony lub wątpliwy projekt. Podejrzewam, że ten pierwszy - mówisz, że "musisz zrobić synchronizację między procesami", ale to naprawdę nie będzie synchronizować niczego. Jeśli proces wywołujący 'WaitOne' faktycznie musi wiedzieć kiedy sygnalizator jest sygnalizowany, dlaczego nie oczekuje synchronicznie? Jeśli nie potrzebuje wiedzieć, dlaczego w ogóle ma semafor? –