2014-07-13 3 views
3

주로 SQLite-net을 사용하여 Windows Phone을 대상으로하는 범용 앱을 작성하고 있습니다.WinRT DownloadProgress 콜백 진행 상태

작동 과정에서 사용자에게 여러 파일을 다운로드 할 수있는 옵션이 제공됩니다. 각 파일 다운로드가 끝날 때마다 db의 파일을 완료로 표시해야합니다. BackgroundDownloader를 사용하여 파일을 다운로드하고 있습니다. WP8.0 응용 프로그램은 Background Transfer Service를 사용했으며 훌륭하게 작동했습니다. 파일은 거대 할 수 있으며 (약 200MB 이상, 사용자 콘텐츠) HttpClient 또는 WebClient에서 다운로드를 래핑하는 것을 기대하지는 않습니다.

그러나 실제로 메서드에서 중단 점이 아니면 진행 대기 콜백이 작동하지 않는 것으로 보입니다.

동작을 보여줍니다 내가 빨리 조립 샘플 응용 프로그램에서 다음 명부

:

모델 :

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

    public bool Done { get; set; } 
    } 

MainPage의 코드 숨김 (나는 단지이 예제의 목적을 위해 여기에 DB를 생성하고 !) :

내가 DownloadProgress 내부에 브레이크 포인트 다음 내가 모두 디버그 메시지를 얻을 F5를 누르면, 내 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"); 
    } 
} 

.

그러나 코드를 실행 시키면 "DONE"이 인쇄되지 않고 내 DB도 업데이트되지 않습니다.

나는 새 작업의 코드를 포장하려 :

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

을 그러나 다시, 난 단지 내가 콜백에서 브레이크 포인트가 'taskrun'를 보게.

업데이트 사실이 상태를 확인하는 것과 관련이 있다고 생각합니다. 예 : 검사 외부의 명령문은 실행되지만 단 한 번만 실행됩니다. 반면 검사 내부의 명령은 실행되지 않습니다.

다운로드가 완료 될 때 해당 콜백을 강제로 호출 할 수있는 방법이 있습니까?

답변

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"); 
    } 

이 날 '에 도착 '할 때마다'.

+0

내 앱에서 이와 동일한 접근 방식을 사용해야했습니다. 완성 된 것은 결코 자기 자신이라고 불려지는 것처럼 보이지 않습니다! 다행이 아니라 다행! – ozziepeeps

+0

완료되지 않았습니다하지만 문제는 GetCurrentDownloadsAsync는 이전 다운로드를 반환합니다. http://stackoverflow.com/questions/27894341/backgrounddownloader-getcurrentdownloadsasync-returns-completed-downloads –

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"); 
    } 
} 

나는이 문제도 가지고 있었고, 나는 이것을 위해 정말로 잘 작동하는 1000ms 동안 자면서 이것을 풀었다.