2016-03-22 27 views
0
i (ı ​​arka plan downloader kullanmak istemiyorum!) Burada indirmek için sınıf kodu internetten bir dosya indirmek bir uygulama geliştirmeyi C# kullanıyorum

:App kapatırsa kullanımı HttpWebRequest

public class DL 
{ 
    public event Progresses OnProgress; 
    Stopwatch stopwatch = new Stopwatch(); 

    public async void Get(string url, StorageFile destinationFile) 
    { 
     stopwatch.Reset(); 
     stopwatch.Start(); 
     HttpWebRequest request = (HttpWebRequest)WebRequest. 
      Create(url); 
     HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync(); 
     long size = response.ContentLength; 
     long downloaded = 0; 


     using (Stream inputStream = response.GetResponseStream()) 
     using (Stream outputStream = await destinationFile.OpenStreamForWriteAsync()) 
     { 
      byte[] buffer = new byte[1024]; 
      int bytesRead; 
      do 
      { 
       bytesRead = inputStream.Read(buffer, 0, buffer.Length); 
       downloaded += bytesRead; 
       outputStream.Write(buffer, 0, bytesRead); 
       int secondsRemaining = (int)(stopwatch.Elapsed.TotalSeconds 
        /downloaded * (size - downloaded)); 
       TimeSpan span = new TimeSpan(0, 0, 0, secondsRemaining); 
       string remainTime = string.Format("{0}:{1}:{2}", span.Hours, span.Minutes, span.Seconds); 
       OnProgress(remainTime); 
      } while (bytesRead != 0); 
     } 
    } 
} 

public delegate void Progresses(string text); 

ve bu dosyayı indirmek için yapılması gerekenler: Ben kullanıcıya Kalan zaman göstermek istiyorum ben indirme düğmesine bastığınızda

private async void btnDownload_Click(object sender, RoutedEventArgs e) 
{ 
    DL webGard = new DL(); 
    webGard.OnProgress += WebGard_OnProgress; 
    StorageFile destinationFile = await KnownFolders.MusicLibrary 
     .CreateFileAsync("r58.zip", CreationCollisionOption.GenerateUniqueName); 
    string url = "my url"; 
    webGard.Get(url, destinationFile); 
} 

private async void WebGard_OnProgress(string text) 
{ 
    System.Diagnostics.Debug.WriteLine(text); 
    var dispatcher = Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher; 
    await dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,() => 
    { 
     textBlock.Text = text; 
    }); 
} 

, uygulaması şu anda askıda gider ve indirme uçlarına kadar bunu kullanamaz ve bu kod üzerinde çalışır Görsel stüdyondaki çıkış pencereleri ancak UI askıya alındı ​​ve textBl'de sonuç gösterilemiyor ock.

Bu sorunu nasıl düzeltebilirim? Teşekkürler

+0

Sadece 'button' düğmesini tıklamanın yanı sıra bazı sınır değerleri ayarlayıp koddan çıkmaya ne dersiniz ..? kodda nerede uygulamanızın kapanmaya başladığını söyler misiniz ..? – MethodMan

cevap

1

Buradaki sorun, başlamak için tüm doğru eşzamansız komutları kullanmanızdır, bu harikadır. Ne yazık ki, aslında veriyi akıştan okuyorsanız, bunu senkronize olarak yapıyorsunuz. İşte demek istediğim ...

Akışlarınızı başlattığınızda, bir döngü kullanarak veri okumaya ve yazmaya başlıyorsunuz. Eğer do/while döngüsüne bakarsanız, tüm işlemlerin senkronize yapıldığını göreceksiniz. Bu döngüde, önemli uygulamanızın askıya alınmasına neden olan iki iş öğesi vardır. Bu hat:

bytesRead = inputStream.Read(buffer, 0, buffer.Length); 

ve bu hattı:

outputStream.Write(buffer, 0, bytesRead); 

Eğer senin sonraki öbek sunucudan geri bir yanıt beklerken uygulama parçacığı engellemek için gidiyoruz sizin döngünün her yineleme sırasında veri. Bu, yalnızca yanıtlamak için sunucuda beklemeniz değil, aynı zamanda bu verileri ağ üzerinden iletme gecikmesini de beklediğiniz anlamına gelir. Bunun üzerine, daha sonra bu verileri dosyanıza geri yazdığınızda dosya sistemi tarafından engellenirsiniz. Bunun yerine, akışın ReadAsync ve WriteAsync yöntemlerini kullanmalısınız.

Bu sayede, verileri gerçekten bellekte taşıdığınız için, yalnızca ana iş parçacığını çok kısa bir süre için engelliyorsunuz. Ardından, uygulamalarınızın kullanıcı arayüzü iş parçacığı istediğini yapmakta serbestken, işlemlerini bitirmek için akışları beklemeye geri döndünüz.

Umarım bu yardımcı olur!

+0

En iyi cevap için teşekkürler. harika çalışıyor. teşekkürler alot – Ramtin

+0

Sorun değil. Bunun size yardımcı olmasına sevindim! –