开发者

Is there a way to implement Caliburn-like co-routines in VB.NET since there's no yield keyword

开发者 https://www.devze.com 2022-12-25 06:30 出处:网络
Note that I\'m aware of other yield in vb.net questions here on SO. I\'m playing around with Caliburn lately. Bunch of great stuff there, including co-routines implementation.

Note that I'm aware of other yield in vb.net questions here on SO.

I'm playing around with Caliburn lately. Bunch of great stuff there, including co-routines implementation.

Most of the work I'm doing is C# based, but now I'm also creating an architecture guideline for a VB.NET only shop, based on Rob's small MVVM framework.

Ev开发者_高级运维erything looks very well except using co-routines from VB. Since VB 10 is used, we can try something like 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

I'm just failing to comprehend how a little more complex co-routine method like the one below (taken from Rob's GameLibrary) could be written 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();
}

Any idea how to achieve that, or any thoughts on using Caliburn co-routines in VB?


Edit:

Marco pointed me to a right direction. After looking in Reflector - Visual Basic code of Rob's GameLibrary, I managed to modify Bill McCarthy's GenericIterator to become a poor man's state machine:

Private _state As Integer = -1

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

And we can use it like this:

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

It definitely isn't as elegant as C# version, but it looks to be doable. We'll see if there are any problems with this. If anyone has better idea, I'm all ears.


As far I understand, the VB workaround relies on the uniformity of the various steps; in other words, it repeats the same action until the exit condition is met.

Caliburn co-routines, instead, are useful in the opposite scenario: unhomogeneous (and asynchronous) steps interlaced with control code; but this is basically a state machine.

Actually, Caliburn leverages C# compiler to obtain a free and automatically generated state machine implementation; so the solution might be to build a simple hand-made state machine just like the one built by C# compiler (see http://blogs.msdn.com/wesdyer/archive/2007/03/23/all-about-iterators.aspx).

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号