在Xamarin iOS上使用async / await从后台提取创建后台安全任务

时间:2017-08-17 06:45:15

标签: xamarin.ios xamarin.forms async-await

我正在编写一个Xamarin Forms应用程序,当应用程序背景时我需要调用REST服务。我应该使用async / await还是会导致问题?

该方案是用户添加新项目,没有网络连接并关闭应用程序。我需要反复检查网络连接,并在有可用时将新数据发布到REST服务。更糟糕的是,数据可能包含照片,因此可能需要几分钟时间。

我尝试的解决方案涉及使用后台提取来检查网络连接,然后启动后台安全任务来完成繁重的工作。这是因为后台提取中运行代码的时间限制为30秒。

一切听起来不错,我的小测试应用似乎有效。我需要帮助的是如何最好地使用async / await来调用REST服务。

以下是一些代码,用于显示测试应用正在执行的操作

public override async void PerformFetch(UIApplication application, Action<UIBackgroundFetchResult> completionHandler)
{
    // kick off a long running task
    await StartLongRunningBackgroundTask();

    // this can be NoData, NewData or Failed
    completionHandler(UIBackgroundFetchResult.NoData);
}

public async Task StartLongRunningBackgroundTask()
{
    _backgroundTaskID = UIApplication.SharedApplication.BeginBackgroundTask(() => {
        // this is called if task times out
        if (_backgroundTaskID != 0)
        {
            UIApplication.SharedApplication.EndBackgroundTask(_backgroundTaskID);
            _backgroundTaskID = 0;
        }
    });

    try
    {
        var restService = FreshTinyIoCContainer.Current.Resolve<IRestClientService>();
        var result = await restService.GetDummyResult();

        var messagingService = FreshTinyIoCContainer.Current.Resolve<IMessagingService>();
        messagingService.Publish(new GotDataMessage { DataString = $"{result.foo} at {DateTime.Now:G}" });
    }

    catch (Exception ex)
    {
        Debug.WriteLine(ex.Message);
    }

    UIApplication.SharedApplication.EndBackgroundTask(_backgroundTaskID);
}

我需要在30秒内从PerformFetch返回。我不确定await是否会这样做,或者我是否应该同步调用StartLongRunningBackgroundTask。

有什么想法吗?以前有人做过这种事吗?

在Android上BTW,我正在使用Firebase Job Dispatcher并且一切正常。

1 个答案:

答案 0 :(得分:2)

应始终异步调用REST服务。但是,如果该呼叫有可能花费超过30秒的限制,您应该查看使用后台传输服务。您可以设置上传/下载以运行已配置的NSUrlSession。要开始使用,请查看walk through以及此post。您基本上要做的是从PerformFetch注册后台任务,iOS将安排它运行。