2

最近 ReactiveUI を使い始めましたが、これまでのところとても良いです。物事を理解しようとしているときに、HttpClient / Refit問題に遭遇しました。長いリストがあり、そのリスト内のすべての項目は、次のように API に要求する必要があります。

これは ReactiveObject です

public SearchResult()
{
    LoadStats = ReactiveCommand.CreateAsyncTask(_ => DownloadMultipleCalls(this.IdText, this.DisplayText));

    LoadStats
        .ThrownExceptions
        .SubscribeOn(RxApp.MainThreadScheduler)
        .Subscribe(ex => UserError.Throw("Couldn't load stats", ex));

    _avaText = LoadStats.Select(x => x.Ava).ToProperty(this, x => x.AvaText, string.Empty);
    _perText = LoadStats.Select(x => x.Per).ToProperty(this, x => x.PerText, string.Empty);

    this.WhenAnyValue(x => x.IdText)
        .Where(x => !string.IsNullOrWhiteSpace(x))
                //.Select(_ => Observable.Timer(DateTimeOffset.MinValue, TimeSpan.FromSeconds(1), RxApp.MainThreadScheduler))
        .Retry(5)
        .InvokeCommand(LoadStats);
}

DownloadMultipleCalls では、次のことが起こっています。

async static Task<AvaPer> DownloadMultipleCalls(string id, string displaytext)
{
    AvaPer response = new AvaPer();
    var block = new ActionBlock<string>(async service =>
    {
        response = await DownloadCall(service, displaytext);
    },
    new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 4 });

    block.Post(id);

    block.Complete();
    await block.Completion;

    return response;
}

async static Task<AvaPer> DownloadCall(string id, string displaytext)
{
    System.Diagnostics.Debug.WriteLine($"Starting download at {DateTimeOffset.Now}");

    var client = new HttpClient(NetCache.UserInitiated)
    {
        BaseAddress = new Uri("https://api.adres.com"),
    };

    //client.Timeout = TimeSpan.FromMilliseconds(10);

    var token = GetToken;

    client.DefaultRequestHeaders.Add("authToken", token);
    var api = RestService.For<IMyApi>(client);

    AvaPer idEntries = new AvaPer();
    try
    {
        var searchResult = await api.GetAvaPerStatusRaw(id); // <== Here is the error (400 - Bad Request)

        //var parsedEntries = Task.Run(() => {
        idEntries = new AvaPer
        {
            Id = searchResult.Id.ToString() ?? string.Empty,
            display = displaytext ?? string.Empty,
            Ava = searchResult.AvailabilityStatus ?? string.Empty,
            Per = searchResult.PerformanceStatus ?? string.Empty,
            Updated = DateTimeOffset.Now.ToLocalTime().ToString() ?? string.Empty
        };
        //}).ConfigureAwait(false);

        //return idEntries;
    }
    catch (ApiException ex)
    {
        var statusCode = ex.StatusCode;
        var error = ex.GetContentAs<Models.ServiceModel.ErrorResponse>();
    }

    return idEntries;
}

最後に、このコード行ですべてがうまくvar searchResult = await api.GetAvaPerStatusRaw(id);いきません。アプリは応答「400 Bad Request」でクラッシュします。エラーを調べると、GET 要求の代わりに id 値がないことがわかります。しかし、初期値を確認すると値がid あるので、それで応答するべきではありません。誰でもこれで私を助けることができますか?ご不明な点がございましたら、お気軽にお問い合わせください。どうもありがとうございました。

敬具、

フェルナンド

4

0 に答える 0