Windows后台任务API异步功能问题

时间:2014-05-06 17:16:20

标签: windows-phone-8 windows-phone windows-8.1 windows-phone-8.1

我在Windows Phone 8.1中使用了计时器触发器后台任务API。

我只想了解此API的基础知识。

我有一个注册计时器触发后台任务的应用程序。每15分钟就会触发一次事件。我知道应用程序的入口点有一个名为RUN的函数。

我正在尝试使用后台传输服务API上传简单的图片。由于此API是异步的,因此我使用BackgroundTaskDeferral来确保后台任务API遵循异步操作。

这是我注意到的,当你将上传作为一个单独的函数并在RUN方法中调用它时,它会在大约10秒内关闭。但是如果您在RUN函数中拥有整个代码,它将持续大约10分钟。

有没有办法可以覆盖这个功能?或任何想法为什么会这样?

public async void Run(IBackgroundTaskInstance taskInstance)
{

    BackgroundTaskDeferral _deferral = taskInstance.GetDeferral();

    //accessMediaUpload();

    StorageFolder picfolder = KnownFolders.CameraRoll;
    var x = await picfolder.GetFilesAsync();
    var enumerator = x.GetEnumerator();

    Debug.WriteLine("Number of files are: " + x.Count);

    while (enumerator.MoveNext())
    {
         var file = enumerator.Current;

         BackgroundUploader uploader = new BackgroundUploader();
         uploader.SetRequestHeader("Filename", file.Name);

         UploadOperation upload = uploader.CreateUpload(uri, file);
         await upload.StartAsync();

         // Get the HTTP response to see the upload result
         ResponseInformation response = upload.GetResponseInformation();
         if (response.StatusCode == 200)
         {
             Debug.WriteLine(file.Name + " Uplaoded");
         }      
     }
     _deferral.Complete();
}

如上所示的代码是RUN方法,它是后台任务的入口点。这里我有一个名为accessMediaUpload()的注释函数。此函数只包含上面显示的代码,用于将文件上载到服务器。

如果拿走内联上传代码并取消注释accessMediaUpload(),后台任务将只运行几秒钟。但上面的代码运行正常。

1 个答案:

答案 0 :(得分:2)

我没有尝试过代码,因为我现在还没有一个有效的例子。但是根据我的理解from MSDN,当你计划运行异步任务并在完成后调用Complete()时,你应该得到Defferal。

BackgroundTaskDeferral _deferral;

public async void Run(IBackgroundTaskInstance taskInstance)
{
    _deferral = taskInstance.GetDeferral();
    accessMediaUpload();
}

private async Task accessMediaUpload()
{
    StorageFolder picfolder = KnownFolders.CameraRoll;
    var x = await picfolder.GetFilesAsync();
    var enumerator = x.GetEnumerator();

    Debug.WriteLine("Number of files are: " + x.Count);

    while (enumerator.MoveNext())
    {
         var file = enumerator.Current;

         BackgroundUploader uploader = new BackgroundUploader();
         uploader.SetRequestHeader("Filename", file.Name);

         UploadOperation upload = uploader.CreateUpload(uri, file);
         await upload.StartAsync();

         // Get the HTTP response to see the upload result
         ResponseInformation response = upload.GetResponseInformation();
         if (response.StatusCode == 200)
         {
             Debug.WriteLine(file.Name + " Uplaoded");
         }      
     }
     _deferral.Complete();
}

几点评论:

  • 请注意,IMO您应该将_deferral.Complete();放入finally try-catch-finally块中 - 只是为了确保即使出现异常也会调用它。正如在MSDN上所说的

      

    小心始终完成所有获得的后台任务延期。系统不会挂起或终止后台主机进程,直到所有挂起的后台任务延迟完成为止。使后台任务延期失效会影响系统管理过程生命周期的能力,并会导致资源泄漏。

  • 上面的方法可能会有所改进,因为你可以单独为每个任务获得Defferal(如果你有多个)并在结尾处调用Complete。这应该允许您运行多个任务并在所有异步任务完成时完成整个BackgroundTask(称为Complete()