Windows phone 7 使用Rx递归调用Windows Phone 7应用程序中的IObservable

Windows phone 7 使用Rx递归调用Windows Phone 7应用程序中的IObservable,windows-phone-7,reactive-programming,Windows Phone 7,Reactive Programming,我们有一个Windows Phone 7应用程序,它使用一组3种使用反应式扩展的服务方法,定义如下: public static class ServiceClient { public static IObservable<string> LookupImage(byte[] image) {...} public static IObservable<XDocument> GetDefinition(string id) {...} pub

我们有一个Windows Phone 7应用程序,它使用一组3种使用反应式扩展的服务方法,定义如下:

public static class ServiceClient
{
    public static IObservable<string> LookupImage(byte[] image) {...}

    public static IObservable<XDocument> GetDefinition(string id) {...}

    public static IObservable<Dictionary<string, byte[]>> GetFiles(string id, string[] fileNames) {...}                
}

如果我弄错了,很抱歉,但是如果我理解正确,您希望使用完全相同的参数重试对LookupImage的调用,直到它返回值为止

解决这一问题的一种简单方法是调用repeat,然后执行(1):

然而,在这个上下文中,没有任何一点允许我们注入处置调用(Take(1)-->OnComplete()-->Auto disposition of subscription中的隐式调用)

您可以通过使用CurrentThread调度程序在后续重新订阅之间提供一些喘息空间来避免这种情况

Observable.Defer(()=>
    ServiceClient.LookupImage(imageBytes)
                 .ObserveOn(Scheduler.CurrentThread)
    )
    .Repeat()
    .Take(1)
    .Subscribe(id =>  ....);
通过对Rx的良好理解和一些创造性,还有其他方法可以实现这一点。(我最想象的是一个调度器)

我想给你一些私人支票。它涵盖了递归和构建您自己的迭代器,而这正是您试图做的

完整代码示例:

private void RunLookupAndRenderLogic()
{   
    byte[] imageBytes = GetImageBytes();

    // There are some cases where the image was not 'interesting' enough in which case GetImageBytes() returns null
    if (pictureBytes != null)
    {
        // Where we have image data, send this to LookupImage service method
        var subscription = Observable
        .Defer(()=>
            ServiceClient.LookupImage(imageBytes)
                     .ObserveOn(Scheduler.CurrentThread)
        )
        .Where(id=>!String.IsNullOrEmpty(id))
        .Repeat()
        .Take(1)
        .Subscribe(id =>      
        {
           // If we have an id, call GetDefinition and GetFiles methods of the service. No further calls to LookupImage should take place.
           RenderLogic(id);   
        });

        //TODO: You dont offer any way to cancel this (dispose of the suscription). 
        //This means you could loop forever :-(
    }
    else
    {
        // If no interesting image was returned, try again
        RunRecognitionAndRenderLogic();
    }
}

(披露:我是IntroToRx.com的作者)

如果我弄错了,我深表歉意,但如果我理解正确,您是否希望使用完全相同的参数重试对LookupImage的调用,直到它返回一个值

解决这一问题的一种简单方法是调用repeat,然后执行(1):

然而,在这个上下文中,没有任何一点允许我们注入处置调用(Take(1)-->OnComplete()-->Auto disposition of subscription中的隐式调用)

您可以通过使用CurrentThread调度程序在后续重新订阅之间提供一些喘息空间来避免这种情况

Observable.Defer(()=>
    ServiceClient.LookupImage(imageBytes)
                 .ObserveOn(Scheduler.CurrentThread)
    )
    .Repeat()
    .Take(1)
    .Subscribe(id =>  ....);
通过对Rx的良好理解和一些创造性,还有其他方法可以实现这一点。(我最想象的是一个调度器)

我想给你一些私人支票。它涵盖了递归和构建您自己的迭代器,而这正是您试图做的

完整代码示例:

private void RunLookupAndRenderLogic()
{   
    byte[] imageBytes = GetImageBytes();

    // There are some cases where the image was not 'interesting' enough in which case GetImageBytes() returns null
    if (pictureBytes != null)
    {
        // Where we have image data, send this to LookupImage service method
        var subscription = Observable
        .Defer(()=>
            ServiceClient.LookupImage(imageBytes)
                     .ObserveOn(Scheduler.CurrentThread)
        )
        .Where(id=>!String.IsNullOrEmpty(id))
        .Repeat()
        .Take(1)
        .Subscribe(id =>      
        {
           // If we have an id, call GetDefinition and GetFiles methods of the service. No further calls to LookupImage should take place.
           RenderLogic(id);   
        });

        //TODO: You dont offer any way to cancel this (dispose of the suscription). 
        //This means you could loop forever :-(
    }
    else
    {
        // If no interesting image was returned, try again
        RunRecognitionAndRenderLogic();
    }
}
(披露:我是IntroToRx.com的作者)