简体   繁体   中英

How to get the individual API call status success response in C#

How to get the individual API call status success response in C#.

I am creating a mobile application using Xamarin Forms,

In my application, I need to prefetch certain information when app launches to use the mobile application.

Right now, I am calling the details like this,

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

In my app I need to update details based on the success response. Something like this (2/5) completed. And the text should be updated whenever we get a new response.

What is the best way to implement this feature? Is it possible to use along with Task.WhenAll. Because I am trying to wrap everything in one method call.

In my app I need to update details based on the success response.

The proper way to do this is IProgress<string> . The calling code should supply a Progress<string> that updates the UI accordingly.

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

If you also need a count, you can either use IProgress<(int, string)> or change how the report progress string is built to include the count.

So here's what I would do in C# 8 and .NET Standard 2.1 :

First, I create the method which will produce the async enumerable:

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

So now you need to await foreach on this task enumerable. Every time you get a return, you know that a task has been finished.

int numberOfFinishedTasks = 0;

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

.WhenAll() will allow you to determine if /any/ of the tasks failed, they you just count the tasks that have failed.

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

No need to over-complicate this. This code will show how many of your tasks had exceptions. Your await task.whenall just triggers them and waits for them to finish. So after that you can do whatever you want with the tasks :)

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.");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM