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

Xamarin.ios 在Xamarin iOS上使用async/await从后台获取创建后台安全任务,xamarin.ios,xamarin.forms,async-await,Xamarin.ios,Xamarin.forms,Async Await,我正在编写一个Xamarin表单应用程序,当该应用程序处于后台时,我需要调用REST服务。我应该使用async/await还是会导致问题 该场景是用户添加新项目,没有网络连接并关闭应用程序。我需要反复检查网络连接,当网络连接可用时,将新数据发布到REST服务。更糟糕的是,数据可能包括照片,因此可能需要几分钟的时间 我尝试的解决方案包括使用后台提取来检查网络连接,然后启动后台安全任务来完成繁重的工作。这是由于后台提取中运行的代码有30秒的限制 这一切听起来不错,我的小测试应用程序似乎工作。我需要的

我正在编写一个Xamarin表单应用程序,当该应用程序处于后台时,我需要调用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);
}
public override async void PerformFetch(UIApplication,Action completionHandler)
{
//开始一项长期的任务
等待惊人的运行背景任务();
//这可以是NoData、NewData或Failed
completionHandler(UIBackgroundFetchResult.NoData);
}
公共异步任务StartongRunningBackgroundTask()
{
_backgroundTaskID=UIApplication.SharedApplication.BeginBackgroundTask(()=>{
//如果任务超时,则调用此函数
如果(_backgroundTaskID!=0)
{
UIApplication.SharedApplication.EndBackgroundTask(\u backgroundTaskID);
_backgroundTaskID=0;
}
});
尝试
{
var restService=FreshTinyIoCContainer.Current.Resolve();
var result=await restService.GetDummyResult();
var messagingService=FreshTinyIoCContainer.Current.Resolve();
发布(在{DateTime.Now:G}处新的GotDataMessage{DataString=$“{result.foo}”);
}
捕获(例外情况除外)
{
Debug.WriteLine(例如消息);
}
UIApplication.SharedApplication.EndBackgroundTask(\u backgroundTaskID);
}
我需要在30秒内从PerformFetch返回。我不确定Wait是否会这样做,或者我是否应该同步调用StartongRunningBackgroundTask

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


顺便说一句,在安卓系统上,我使用的是Firebase作业调度程序,一切都很好。

调用REST服务应该始终异步完成。但是如果通话时间超过30秒的限制,你应该考虑使用后台转接服务。您可以将上载/下载设置为通过配置的文件运行。为了让您开始,请看一看这个以及这个。基本上,您要做的是从您的
PerformFetch
注册后台任务,iOS将安排它运行。

我花了几天时间研究后台传输服务,决定不使用它。我所有的REST代码都在一个共享服务中,我可以从Android和iOS调用该服务。我使用Refit包装REST服务,并在其中包含调用和错误处理代码。如果我使用BTS,我将不得不重写所有这些,并使用iOS特定的NSURLSession。我正试图找出如何最好地使用后台安全任务,因为这给了我最多600秒的时间来发布数据。