I am writing a universal app primarily targeting Windows Phone using SQLite-net.
During the course of operation, the user is presented with an option to download multiple files. At the end of each file download, I need to mark the file in the db as completed. I am using BackgroundDownloader in order to download files - the WP8.0 app used Background Transfer Service and that worked great. Files can be huge (some 200+ mbs, user content) and i am not looking forward to wrapping the downloads in the HttpClient or WebClient.
However, it seems that the progress callback doesn't work with awaits unless I actually breakpoint in the method.
The following are listings from a sample app i quickly put together that demonstrates the behaviour:
Model:
public class Field
{
[PrimaryKey]
[AutoIncrement]
public int Id { get; set; }
public bool Done { get; set; }
}
MainPage codebehind (i am creating a db here only for the purposes of this example!):
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");
}
}
If i breakpoint inside the DownloadProgress and then press F5 i get both Debug messages, and my db gets a new record.
However, if i just let the code execute, i never see "DONE" printed to me and neither is my db updated.
I tried wrapping the code in a new task:
await Task.Run(
async () =>
{
Debug.WriteLine("taskrun");
.... OTHER CODE FROM ABOVE...
});
But again, i only get to see 'taskrun' if i breakpoint in the callback.
UPDATE I actually think this is more related to checking the status. E.g. the statements outside of the check are executed, but only once, whereas anything inside the check is not executed.
Is there any way to force that callback to be invoked when the download is completed?