6

请注意,我知道关于 SOvb.net问题中的其他产量。

我最近在玩Caliburn。那里有很多很棒的东西,包括协同程序的实现。

我所做的大部分工作都是基于 C# 的,但现在我还在为仅 VB.NET 的商店创建架构指南,基于 Rob 的小型 MVVM 框架

除了使用 VB 中的协程外,一切看起来都很好。由于使用了 VB 10,我们可以尝试类似Bill McCarthy 的建议

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

我只是无法理解如何用 VB 编写更复杂的协程方法,例如下面的方法(取自 Rob 的 GameLibrary):

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();
}

知道如何实现这一点,或者对在 VB 中使用 Caliburn 协同程序有什么想法吗?


编辑:

Marco为我指明了正确的方向。在查看 Reflector - Rob 的 GameLibrary 的 Visual Basic 代码后,我设法将 Bill McCarthy 的 GenericIterator 修改为穷人的状态机:

Private _state As Integer = -1

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

我们可以这样使用它:

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

它绝对没有 C# 版本那么优雅,但它看起来是可行的。我们会看看这是否有任何问题。如果有人有更好的主意,我会全神贯注。

4

1 回答 1

3

据我了解,VB 解决方法依赖于各个步骤的一致性;换句话说,它重复相同的动作,直到满足退出条件。

相反,Caliburn 协同程序在相反的情况下很有用:非同质(和异步)步骤与控制代码交错;但这基本上是一个状态机。

实际上,Caliburn 利用 C# 编译器来获得一个免费的、自动生成的状态机实现;因此解决方案可能是构建一个简单的手工状态机,就像由 C# 编译器构建的状态机一样(参见http://blogs.msdn.com/wesdyer/archive/2007/03/23/all-about-iterators。 .aspx)。

于 2010-03-27T16:06:10.503 回答