Guida alla libreria asincrona

3

Sto creando una libreria che contiene una classe che espone diversi metodi Async:

public class MyClass {
  public async Task<Foo> DoFooAsync() { /*...*/ }
  public async Task<Bar> DoBarAsync() { /*...*/ }
}

Ho due (principali) domande a riguardo:

  1. Capisco che non tutti amano (o hanno bisogno di) lavorare in modo asincrono; è facile per qualcuno che usa la mia libreria invocare questi metodi in modo sincrono. Tuttavia, non sarà molto importante fornire wrapper sincrono per il metodo asincrono in modo che la classe fornisca anche un metodo public Foo DoFoo() e public Bar DoBar() .

    • Devo fornire questi metodi o devo consentire alle persone di implementare i propri?
    • Se fornisco questi metodi, dovrei:
      1. Crea un metodo private T ExecuteFunctionSynchronously<T>(Func<T> func) e i metodi sincroni richiamano questo ExecuteFunctionSynchronously internamente o ...
      2. ... ogni metodo sincrono dovrebbe chiamare il metodo async 'waterfall style' (quindi DoFoo() esegue return DoFooAsync().Result (o qualcosa del genere) internamente?
  2. La classe avrà in seguito un "message loop" che legge continuamente dati provenienti da un socket (atteso). Voglio che questo ciclo di messaggi continui 'eternamente'. Voglio che la classe sia facilmente utilizzabile da tutti.

    • Che tipo di 'stile' dovrei usare per questo messageloop per notificare agli utenti di MyClass che qualcosa è successo?
      1. Eventi (ad esempio MyClass.FooReceived += myhandler )?
      2. Callback (ad esempio MyClass.StartListening(myhandler) )?
      3. Qualcosa di "attendibile" (ad esempio while (await MyClass.GetFoo()) { ... } )?
      4. Reattivo (Rx)?
      5. Qualcosa di diverso da sopra, cioè ...

In primo luogo sto chiedendo una guida sullo "stile"; come ti avvicineresti a questo e come pensi che una libreria (principalmente) asincrona dovrebbe fornire un'interazione (API savoise) mantenendo al tempo stesso internals e messageloops fuori dalla mente dell'utente senza esporre troppo di ciò che sta accadendo internamente.

    
posta RobIII 25.06.2015 - 21:34
fonte

2 risposte

2

Should I provide these methods or should I let people implement their own?

Dovresti evitare di farlo. Stephen Toub spiega perché nel suo articolo Devo esporre i wrapper sincroni per i metodi asincroni ? Il motivo per cui questo è un problema con alcune insidie, semplice .Result può sembrare funzionare per te, ma potrebbe fallire (o meglio, deadlock) in altre situazioni.

What kind of 'style' should I use for this messageloop to notify users of MyClass that something has happened?

Penso che dipenda dal tipo di notifiche che stai esponendo, da cosa i tuoi utenti vorranno fare con loro e cosa si sentirà più naturale per loro. C'è un motivo per cui esistono tutti questi stili diversi.

    
risposta data 10.07.2015 - 19:14
fonte
0

Should I provide these methods or should I let people implement their own?

Sto cercando di trovare il post (penso che sia stato Stephen Cleary su SO), ma una delle risposte aveva chiarito che preferiva rendere le sue operazioni sincrone e lasciare che il cliente decidesse se volevano chiamarle in modo asincrono o no.

È rimasto con me perché era Stephen Cleary e mi piaceva l'idea che il tuo codice possa essere usato allo stesso modo senza doverlo pensare, o può essere avvolto in un wrapper asincrono, che richiede un po 'di più pensato ma è il lavoro che stai scegliendo di assumere.

Questo, rispetto alla situazione opposta in cui devi pensare e dedicare più impegno all'uso di una libreria nel modo sincrono standard a cui siamo generalmente abituati.

    
risposta data 14.08.2015 - 16:25
fonte