获得异步等待和任务工作

时间:2014-06-11 13:44:23

标签: c# asynchronous xamarin.ios async-await restsharp

我正在尝试构建一个调用rest API的MonoTouch应用程序,然后处理它返回的数据。我已经成功地完成了这项工作,但我现在正试图使其异步,并在处理时显示“等待”叠加层。我现在已经使用RestSharp ExecuteAsync方法调用了工作,但是我不知道如何使用响应来更新我的UI。

这是在我调用我的API类的ViewController中:

public partial class TestViewController : UIViewController
{
    partial void LoginButton_click(UIButton sender)
    {
        hud = new MTMBProgressHUD(View)
        {
            LabelText = "Waiting...",
            RemoveFromSuperViewOnHide = true,
        };

        View.AddSubview(hud);
        hud.Show(animated: true);


        APIClient ApiClient = new APIClient();
        TestAPI cd = new TestAPI(ApiClient);
        cd.TestApiCall(1, 123); //Could send this as sender parameter

        //Need to call this once the API call is complete
        //hud.Hide(animated: true);

    }
}

这是我的TestAPI类,其中调用了api:

class TestAPI
{
    APIClient API;
    public TestAPI(APIClient APIClient)
    {
        this.API = APIClient;
    }

    public void TestApiCall(int userId, int PIN)
    {
        RestRequest request = new RestRequest("TestCall", Method.POST);

        OpenRequest obj = new OpenRequest
        {
            User = userId,
            PIN = PIN
        };

        request.AddObject(obj);

        API.client.ExecuteAsync(request, response =>
        {
            callback(response.Content);
        });
    }
    private void callback(string p)
    {
        //Could pass through the sender from the API call then do: sender.DismissHUD();

        throw new NotImplementedException();
    }
}

我已经阅读了很多关于异步,任务和等待但我似乎无法让他们以我想要的方式使用RestSharp。我可以将调用ViewController方法作为sender参数发送,当创建TestAPI类,然后在回调函数中引用它时,但这不会使代码在应用程序的其他地方非常可重用。

1 个答案:

答案 0 :(得分:2)

我们可以做的是将RestClient.ExecuteAsync<T>包装在返回Task<T>的方法中,并在TaskCompletionSource的帮助下使用任务异步模式实现

首先,让我们将ExecuteAsync<T>调用包装在TestAPI类中:

class TestAPI
{
    APIClient API;
    public TestAPI(APIClient APIClient)
    {
        this.API = APIClient;
    }

    public Task<T> ExecuteAsync<T>() where T : new()
    {
        var client = new RestClient();
        var taskCompletionSource = new TaskCompletionSource<T>();

        RestRequest request = new RestRequest("TestCall", Method.POST);

        OpenRequest obj = new OpenRequest
        {
            User = userId,
            PIN = PIN
        };

        request.AddObject(obj);
        try
        {
            client.ExecuteAsync<T>(request, (response) => taskCompletionSource.SetResult(response.Data));
        }
        catch (Exception e)
        {
            taskCompletionSource.SetException(e);
        }

        return taskCompletionSource.Task;
    }
}

现在,您可以在控制器内await进行呼叫:

public partial class TestViewController : UIViewController
{
    // I Assume this is a top level event handler, hence why
    // it returns void and not Task
    public async void LoginButton_click(UIButton sender)
    {
        hud = new MTMBProgressHUD(View)
        {
            LabelText = "Waiting...",
            RemoveFromSuperViewOnHide = true,
        };

        View.AddSubview(hud);
        hud.Show(animated: true);


        APIClient ApiClient = new APIClient();
        TestAPI cd = new TestAPI(ApiClient);
        var apiResponse = await cd.ExecuteAsync<YourType>();

        hud.Hide(animated: true);

    }
}