WinRT DownloadProgress回调进度状态

时间:2014-07-13 07:09:09

标签: c# sqlite windows-runtime windows-phone-8.1

我正在编写一个主要针对使用SQLite-net的Windows Phone的通用应用程序。

在操作过程中,向用户提供下载多个文件的选项。在每次文件下载结束时,我需要将db中的文件标记为已完成。我正在使用BackgroundDownloader来下载文件 - WP8.0应用程序使用了后台传输服务,效果很好。文件可能很大(大约200多万桶,用户内容),我不期待将下载包装在HttpClient或WebClient中。

但是,除非我在方法中实际断点,否则似乎进度回调不能等待。

以下是我快速整理的示例应用程序列表,演示了行为:

型号:

   public class Field
  {
    [PrimaryKey]
    [AutoIncrement]
    public int Id { get; set; }

    public bool Done { get; set; }
  }

MainPage codebehind(我在这里仅为了这个例子的目的创建一个db!):

 private async void Button_Click(object sender, RoutedEventArgs e)
{
  using (var db = new SQLiteConnection(Windows.Storage.ApplicationData.Current.LocalFolder.Path + "//Main.db"))
  {
    db.CreateTable<Field>();
    db.Commit();
  }

  this.DbConnection = new SQLiteAsyncConnection(Windows.Storage.ApplicationData.Current.LocalFolder.Path + "//My.db");
  var dl = new BackgroundDownloader();
  dl.CostPolicy = BackgroundTransferCostPolicy.Always;
  var transferUri = new Uri("http://192.168.1.4/hello.world", UriKind.Absolute);
  var folder = await ApplicationData.Current.LocalFolder.CreateFolderAsync(
    "Content",
    CreationCollisionOption.OpenIfExists);

  var localFile = await folder.CreateFileAsync("cheesecakes.file", CreationCollisionOption.ReplaceExisting);
  var d = dl.CreateDownload(transferUri, localFile);
  d.Priority = BackgroundTransferPriority.High;

  var progressCallback = new Progress<DownloadOperation>(this.DownloadProgress);

  await d.StartAsync().AsTask(progressCallback);
}

private async void DownloadProgress(DownloadOperation download)
{
  Debug.WriteLine("Callback");
  if (download.Progress.Status == BackgroundTransferStatus.Completed)
  {
        var f = new Field();
        f.Done = true;
        await this.DbConnection.InsertAsync(f);
        Debug.WriteLine("DONE");
   }
}

如果我在DownloadProgress中断点然后按F5我会收到两条调试消息,我的数据库会获得一条新记录。

然而,如果我只是让代码执行,我永远不会看到&#34; DONE&#34;打印给我,我的数据库都没有更新。

我尝试将代码包装在一个新任务中:

await Task.Run(
      async () =>
      {
        Debug.WriteLine("taskrun");
       .... OTHER CODE FROM ABOVE...
      });

但是,我只能看到&#39; taskrun&#39;如果我在回调中断点。

更新我实际上认为这与检查状态更相关。例如。检查之外的语句只执行一次,而检查中的任何内容都不会执行。

有没有办法强制在下载完成后调用该回调?

2 个答案:

答案 0 :(得分:2)

private async void DownloadProgress(DownloadOperation download)
{
    Debug.WriteLine("Callback");

    var value = download.Progress.BytesReceived * 100 download.Progress.TotalBytesToReceive;
    new System.Threading.ManualResetEvent(false).WaitOne(1000);
    if (download.Progress.Status == BackgroundTransferStatus.Completed )
    {
        var f = new Field();
        f.Done = true;
        await this.DbConnection.InsertAsync(f);
        Debug.WriteLine("DONE");
    }
}

我也有这个问题,我通过睡眠1000毫秒来解决这个问题,这对我来说非常有用。

答案 1 :(得分:1)

不确定是什么导致这种情况,但我能够通过手动检查要下载的字节而不依赖于DownloadOperation.Progress.Status来使示例应用程序可靠地工作:

 private async void DownloadProgress(DownloadOperation download)
{
  Debug.WriteLine("Callback");

  var value = download.Progress.BytesReceived * 100 / download.Progress.TotalBytesToReceive;

  if (download.Progress.Status == BackgroundTransferStatus.Completed || value >= 100)
  {
    var f = new Field();
    f.Done = true;
    await this.DbConnection.InsertAsync(f);
    Debug.WriteLine("DONE");
  }

每次都让我'完成'。