我正在编写一个主要针对使用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;如果我在回调中断点。
更新我实际上认为这与检查状态更相关。例如。检查之外的语句只执行一次,而检查中的任何内容都不会执行。
有没有办法强制在下载完成后调用该回调?
答案 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");
}
每次都让我'完成'。