Avvolgere un oggetto AutoResetEvent in un WaitHandle ristretto?
-
26-10-2019 - |
Domanda
Ho costruito una libreria che lanci un filo per farlo di cosa e restituisce un WaitHandle al chiamante.
Guardando un bug report, ho il sospetto il codice che sta chiamando mia biblioteca sta prendendo l'oggetto restituito e il cast a un AutoResetEvent (che è) e alzando la bandiera stessa. Non è destinato a farlo.
C'è un modo per avvolgere l'oggetto AutoResetEvent con uno che può ancora essere WaitOne'd e WaitAny'd, ma può essere sollevata solo dal mio codice?
Grazie.
Soluzione
È possibile creare una nuova classe derivata da EventWaitHandle
e di override Set
e Reset
così non fanno nulla, o un'eccezione. In realtà, si dovrebbe creare implementazioni new
, dal momento che Set
e Reset
non sono virtuali. Naturalmente, dovreste creare i propri, altri metodi nome. Come MyInternalSet
e MyInternalReset
. Possibile, ma io non lo consiglio a farlo.
Invece vorrei documentare che il cliente non deve impostare o reimpostare l'evento, perché così facendo causare comportamenti imprevedibili.
Si potrebbe creare una classe WaitHandle
-derived che contiene il AutoResetEvent
come una proprietà internal
. codice del client, allora non sarebbe in grado di accedervi. Qualcosa di simile:
public class MyWaitHandle: WaitHandle
{
internal AutoResetEvent InternalEvent { get; private set; }
internal MyWaitHandle(AutoResetEvent event)
{
InternalEvent = event;
}
public override bool WaitOne(int32 timeout)
{
return InternalEvent.WaitOne();
}
}
Si dovrà eseguire l'override del metodo Dispose(Boolean)
protetta, in modo che possa smaltire la maniglia interna, e si vorrà gli altri sovraccarichi WaitOne
, pure. È quindi possibile creare implementazioni internal
di Set
e Reset
, o semplicemente avere il vostro InternalHandle.Set
codice di chiamata.
penso ancora che il miglior modo di agire è quello di dire al cliente di non farlo. Ma se si deve evitare che, quanto sopra dovrebbe funzionare.