【问题标题】:How to get the individual API call status success response in C#如何在 C# 中获取单个 API 调用状态成功响应
【发布时间】:2019-06-03 12:37:00
【问题描述】:

如何在 C# 中获取单个 API 调用状态成功响应。

我正在使用 Xamarin Forms 创建一个移动应用程序,

在我的应用程序中,我需要在应用程序启动时预取某些信息才能使用移动应用程序。

现在,我这样称呼细节,

    public async Task<Response> GetAllVasInformationAsync()
    {
        var userDetails = GetUserDetailsAsync();
        var getWageInfo = GetUserWageInfoAsync();
        var getSalaryInfo = GetSalaryInfoAsync();


        await Task.WhenAll(userDetails,
            getWageInfo,
            getSalaryInfo,
          );

        var resultToReturn = new Response
        {
            IsuserDetailsSucceeded = userDetails.Result,
            IsgetWageInfoSucceeded = getWageInfo.Result,
            IsgetSalaryInfoSucceeded = getSalaryInfo.Result,
        };

        return resultToReturn;
    }

在我的应用中,我需要根据成功响应更新详细信息。这样的事情(2/5)完成了。每当我们收到新的回复时,都应该更新文本。

实现此功能的最佳方式是什么?是否可以与 Task.WhenAll 一起使用。因为我试图将所有内容都包装在一个方法调用中。

【问题讨论】:

  • 为了澄清,您正在寻找进度更新?它从 (0/5) 完成开始,然后当第一个任务完成时,您希望 (1/5) 完成......等等。或者您想跟踪实际成功/失败的 Api 调用次数?
  • 这似乎是异步 foreach 的一个案例(仅在 c# 8.0 中添加了支持):docs.microsoft.com/en-us/dotnet/csharp/language-reference/… 这不是您要找的东西吗?

标签: c# xamarin.forms task


【解决方案1】:

在我的应用中,我需要根据成功响应更新详细信息。

执行此操作的正确方法是IProgress&lt;string&gt;。调用代码应提供一个 Progress&lt;string&gt; 相应地更新 UI。

public async Task<Response> GetAllVasInformationAsync(IProgress<string> progress)
{
  var userDetails = UpdateWhenComplete(GetUserDetailsAsync(), "user details");
  var getWageInfo = UpdateWhenComplete(GetUserWageInfoAsync(), "wage information");
  var getSalaryInfo = UpdateWhenComplete(GetSalaryInfoAsync(), "salary information");

  await Task.WhenAll(userDetails, getWageInfo, getSalaryInfo);

  return new Response
  {
    IsuserDetailsSucceeded = await userDetails,
    IsgetWageInfoSucceeded = await getWageInfo,
    IsgetSalaryInfoSucceeded = await getSalaryInfo,
  };

  async Task<T> UpdateWhenComplete<T>(Task<T> task, string taskName)
  {
    try { return await task; }
    finally { progress?.Report($"Completed {taskName}"); }
  }
}

如果您还需要计数,您可以使用IProgress&lt;(int, string)&gt; 或更改报告进度字符串的构建方式以包含计数。

【讨论】:

  • 妈的,这么简单
  • 这很漂亮 :) 感谢您的帮助
【解决方案2】:

这就是我在 C# 8.NET Standard 2.1 中要做的事情:

首先,我创建将产生异步枚举的方法:

static async IAsyncEnumerable<bool> TasksToPerform() {
    Task[] tasks = new Task[3] { userDetails, getWageInfo, getSalaryInfo };

    for (i = 0; i < tasks.Length; i++) {
        await tasks[i];
        yield return true;
    }
}

所以现在你需要在这个可枚举的任务上等待 foreach。每次得到回报,就知道任务完成了。

int numberOfFinishedTasks = 0;

await foreach (var b in TasksToPerform()) {
    numberOfFinishedTasks++;
    //Update UI here to reflect the finished task number
}

【讨论】:

  • 但是在这种情况下,我如何知道哪个任务失败,哪个任务成功?只是告诉天气任务已经完成还是不正确?有什么方法可以让我了解失败和成功的状态。
  • 在这种情况下,任务本身需要返回一些关于它们是否失败的信息。因此它们不会是Task 类型,而是例如Task&lt;bool&gt;,如果成功则返回true,否则返回false。或者他们可以返回一个自定义类型,其中包含有关失败的信息。
  • 我认为 IAsyncEnumerable 在 Xamarin 表单中不可用 stackoverflow.com/questions/55821746/…
  • 我不知道!但是获得预览版,你应该可以使用它,不是吗?
【解决方案3】:

无需过于复杂。此代码将显示您的任务中有多少异常。您的 await task.whenall 只是触发它们并等待它们完成。所以在那之后你可以对任务做任何你想做的事情:)

var task = Task.Delay(300);
var tasks = new List<Task> { task };
var faultedTasks = 0;

tasks.ForEach(t =>
{
     t.ContinueWith(t2 =>
     {
          //do something with a field / property holding ViewModel state
          //that your view is listening to
     });
});

await Task.WhenAll(tasks);

//use this to respond with a finished count
tasks.ForEach(_ => { if (_.IsFaulted) faultedTasks++; });

Console.WriteLine($"{tasks.Count() - faultedTasks} / {tasks.Count()} completed.");

【讨论】:

  • 您正在等待所有任务以这个答案结束。这不是 op 想要的。他查看了有多少已启动的任务已经完成。
  • 你是对的,所以我对其进行了编辑,以便在事情发生时查看它们 :)
【解决方案4】:

.WhenAll() 将允许您确定 /any/ 任务是否失败,您只需计算失败的任务。

public async Task<Response> GetAllVasInformationAsync()
{
    var userDetails = GetUserDetailsAsync();
    var getWageInfo = GetUserWageInfoAsync();
    var getSalaryInfo = GetSalaryInfoAsync();


    await Task.WhenAll(userDetails, getWaitInfo, getSalaryInfo)
       .ContinueWith((task) =>
       {
          if(task.IsFaulted)
          { 
             int failedCount = 0;
             if(userDetails.IsFaulted) failedCount++;
             if(getWaitInfo.IsFaulted) failedCount++;
             if(getSalaryInfo.IsFaulted) failedCount++;
             return $"{failedCount} tasks failed";
          }
    });

    var resultToReturn = new Response
    {
        IsuserDetailsSucceeded = userDetails.Result,
        IsgetWageInfoSucceeded = getWageInfo.Result,
        IsgetSalaryInfoSucceeded = getSalaryInfo.Result,
    };

    return resultToReturn;
}

【讨论】:

  • 有什么方法可以跟踪哪个任务成功哪个任务失败。
猜你喜欢
  • 2015-10-26
  • 1970-01-01
  • 2021-08-29
  • 2021-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-17
相关资源
最近更新 更多