2010-03-26 18 views
6

notare che io sono a conoscenza di altre yieldinvb.net domande qui su SO.C'è un modo per implementare Caliburn-come co-routine in VB.NET poiché non c'è resa parola chiave

Ultimamente sto giocando con Caliburn. Un mucchio di grandi cose lì, compresa l'implementazione co-routines.

Gran parte del lavoro che sto svolgendo è basato su C#, ma ora sto anche creando una linea guida per l'architettura per un solo negozio VB.NET, basato su Rob's small MVVM framework.

Tutto sembra molto bene tranne l'utilizzo di routine di routine da VB. Dal momento che VB 10 è usato, siamo in grado di provare qualcosa di simile Bill McCarthy's suggestion:

Public Function Lines(ByVal rdr as TextReader) As IEnumerable(Of String) 
    Return New GenericIterator(Of String) 
      (Function(ByRef nextItem As String) As Boolean 
       nextItem = rdr.ReadLine 
       Return nextItem IsNot Nothing 
      End Function) 
End Function 

Sto solo non riuscendo a comprendere come un metodo poco co-routine di più complessa come quella qui sotto (tratta da GameLibrary di Rob) potrebbe essere scritta in VB:

public IEnumerable<IResult> ExecuteSearch() 
{ 
    var search = new SearchGames 
    { 
     SearchText = SearchText 
    }.AsResult(); 

    yield return Show.Busy(); 
    yield return search; 

    var resultCount = search.Response.Count(); 

    if (resultCount == 0) 
     SearchResults = _noResults.WithTitle(SearchText); 
    else if (resultCount == 1 && search.Response.First().Title == SearchText) 
    { 
     var getGame = new GetGame 
     { 
      Id = search.Response.First().Id 
     }.AsResult(); 

     yield return getGame; 
     yield return Show.Screen<ExploreGameViewModel>() 
      .Configured(x => x.WithGame(getGame.Response)); 
    } 
    else SearchResults = _results.With(search.Response); 

    yield return Show.NotBusy(); 
} 

Qualche idea su come ottenerlo o su come utilizzare le co-routine Caliburn in VB?


Edit:

Marco mi ha segnalato una giusta direzione. Dopo aver guardato in Reflector - codice Visual Basic di GameLibrary di Rob, sono riuscito a modificare la GenericIterator di Bill McCarthy a diventare macchina a stati di un uomo povero:

Private _state As Integer = -1 

Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext 
    _state += 1 
    Return _func(_Current, _state) 
End Function 

e possiamo usare in questo modo:

Public Function ExecuteSearch() As IEnumerable(Of String) 
    ' If we need some variable shared across states, define it here 
    Dim someSharedStuff As String = String.Empty 

    ' Notice the second lambda function parameter below - state 
    Return New GenericIterator(Of IResult) 
     (Function(ByRef nextItem As IResult, state As Integer) As Boolean 
      Select Case state 
       Case 0 
        someSharedStuff = "First state" 
        nextItem = Show.Busy 
        Return True 
       Case 1 
        nextItem = Show.SomeLoadingScreen 
        ' Do some additional processing here... 
        Return True 
       Case 2 
        ' Do something with someSharedStuff variable... 
        Console.WriteLine(someSharedStuff) 
        nextItem = PerforSomemWebServiceCall() 
        Return True 
       '... 
       Case 6 
        nextItem = Show.NotBusy 
        Return False 
      End Select 

      Return False 
     End Function) 

End Function 

E ' sicuramente non è elegante come la versione C#, ma sembra fattibile. Vedremo se ci sono problemi con questo. Se qualcuno ha un'idea migliore, sono tutto orecchie.

risposta

3

Per quanto ho capito, la soluzione VB si basa sull'uniformità delle varie fasi; in altre parole, ripete la stessa azione fino a quando non viene soddisfatta la condizione di uscita.

Le coordinazioni di caliburn, invece, sono utili nello scenario opposto: passaggi non omogenei (e asincroni) interlacciati con il codice di controllo; ma questa è fondamentalmente una macchina di stato.

In realtà, Caliburn utilizza il compilatore C# per ottenere un'implementazione della macchina a stati libera e generata automaticamente; quindi la soluzione potrebbe essere quella di costruire una semplice macchina di stato fatta a mano proprio come quella costruita dal compilatore C# (vedi http://blogs.msdn.com/wesdyer/archive/2007/03/23/all-about-iterators.aspx).

+0

Ottima risposta, hai praticamente inchiodato il problema e la possibile soluzione lì. Spero di essere riuscito a creare un'implementazione iniziale per la macchina a stati (anche se non molto elegante), dopo aver esaminato l'output generato dal compilatore in Reflector - codice Visual Basic. La domanda viene aggiornata con questa implementazione. Ho ancora intenzione di leggere l'articolo di Wes Dyer, sembra avere alcune buone informazioni sugli iteratori. Grazie! –