Quando è sicuro usare Monitor (lock) con Task?

3

In un ambiente multi-thread, dobbiamo considerare l'accesso simultaneo alle risorse scrivibili. Un approccio comune è usare Monitor o la sua forma abbreviata lock .

Task è a un diverso livello di astrazione rispetto a Thread . Un'attività può essere eseguita su un thread (e in base ai log, lo fanno nella nostra applicazione), ma ciò non è garantito. Vedi per es. Qual è la differenza tra attività e thread? :

If the value you are waiting for comes from the filesystem or a database or the network, then there is no need for a thread to sit around and wait for the data when it can be servicing other requests. Instead, the Task might register a callback to receive the value(s) when they're ready.

Cioè, quel tipo di Task condivide in qualche modo un Thread con altro codice in esecuzione (devo ammettere che non capisco come funzioni in dettaglio, attualmente mi sembra una specializzazione del "famoso" DoEvents ).

Di conseguenza, Monitor non sarà in grado di distinguerli, e - poiché Monitor può essere rientranti - consentire a entrambi di accedere alla risorsa. Cioè, Monitor "fallisce."

Esempi con Threads generalmente usano Monitor tuttavia. Quindi voglio chiedere come posso essere sicuro che Monitor sia sicuro con un Task (oppure: come posso essere sicuro che una Task sia in esecuzione su un Thread del proprio).

    
posta Bernhard Hiller 18.01.2017 - 12:01
fonte

1 risposta

3

So I want to ask how I can be sure that Monitor is safe with a Task (or: how can I be sure that a Task is running on a Thread of its own).

Non lo fai. Non dovresti usare Monitor in un'operazione asincrona proprio perché non puoi garantire questo (e non vorremmo neanche se tu potessi).

La soluzione consiste nell'utilizzare diversi meccanismi di sincronizzazione progettati per funzionare correttamente in un contesto asincrono. Ad esempio, non devono utilizzare l'affinità di thread e vorrete anche che siano essi stessi asincroni, anziché attendere in modo sincrono l'accesso alla sezione critica.

La risposta è usare SemaphoreSlim , che ha un metodo WaitAsync che puoi await . Supponendo di avere una sezione critica tradizionale, è possibile impostare il semaforo per consentire solo 1 operazione simultanea. Usando questo, se un thread ottiene l'accesso al semaforo, quindi avvia un'operazione asincrona e va a fare qualcos'altro che anche prova ad accedere al semaforo, non avrà accesso. Significa anche che non avrai problemi a rilasciare il semaforo da un thread diverso da quello da cui lo hai acquisito.

    
risposta data 19.01.2017 - 21:30
fonte

Leggi altre domande sui tag