Downloading and saving a file Async in Windows Phone 8

前端 未结 3 869
走了就别回头了
走了就别回头了 2020-12-11 08:04

How can I download and save a file to IsolatedStorage asynchronously? I used WebClient first for the purpose, but I couldn\'t await till completion

相关标签:
3条回答
  • 2020-12-11 08:22

    This, what har07 posted, should work. In case you need to extend your method a little, I would try to do something like this (though it is not tested, but should work):

    (Rebuilt after comment - with Cancellation)

    // first define Cancellation Token Source - I've made it global so that CancelButton has acces to it
    CancellationTokenSource cts = new CancellationTokenSource();
    enum Problem { Ok, Cancelled, Other }; // results of my Task
    
    // cancelling button event
    private void CancellButton_Click(object sender, RoutedEventArgs e)
    {
       if (this.cts != null)
            this.cts.Cancel();
    }
    
    // the main method - I've described it a little below in the text
    public async Task<Problem> DownloadFileFromWeb(Uri uriToDownload, string fileName, CancellationToken cToken)
    {
       try
       {
           using (Stream mystr = await DownloadFile(uriToDownload))
               using (IsolatedStorageFile ISF = IsolatedStorageFile.GetUserStoreForApplication())
               {
               if (ISF.FileExists(fileName)) return Problem.Other;
               using (IsolatedStorageFileStream file = ISF.CreateFile(fileName))
               {
                   const int BUFFER_SIZE = 1024;
                   byte[] buf = new byte[BUFFER_SIZE];
    
                   int bytesread = 0;
                   while ((bytesread = await mystr.ReadAsync(buf, 0, BUFFER_SIZE)) > 0)
                   {
                      cToken.ThrowIfCancellationRequested();
                      file.Write(buf, 0, bytesread);
                   }
               }
           }
           return Problem.Ok;
        }
        catch (Exception exc)
        {
           if (exc is OperationCanceledException)
               return Problem.Cancelled;
           else return Problem.Other; 
        }
    }
    
    // and download
    private async void Downlaod_Click(object sender, RoutedEventArgs e)
    {
       cts = new CancellationTokenSource();
       Problem fileDownloaded = await DownloadFileFromWeb(new Uri(@"http://filedress/myfile.txt", UriKind.Absolute), "myfile.txt", cts.Token);
       switch(fileDownloaded)
       {
          case Problem.Ok:
               MessageBox.Show("File downloaded");
               break;
          case Problem.Cancelled:
               MessageBox.Show("Download cancelled");
               break;
          case Problem.Other:
          default:
               MessageBox.Show("Other problem with download");
               break;
        }
    }
    

    I've added Cancellation Token - it means that your download operation can be cancelled after Button.Click. On the other hand if await DownloadFile(uriToDownload) is Cancelled it automatically throws OperationCancelled - then you catch that exception and return adequate result.

    I haven't run that code, but it may show the main idea.

    0 讨论(0)
  • 2020-12-11 08:34

    Try something like this (not tested) :

    try
    {
        using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
        {
            IsolatedStorageFileStream fileStream = myIsolatedStorage.CreateFile("fileNameHere");
    
            BitmapImage bitmap = new BitmapImage();
            var stream = await DownloadFile(new Uri("http://someuri.com", UriKind.Absolute));
            bitmap.SetSource(stream);
            WriteableBitmap wb = new WriteableBitmap(bitmap);
    
            // Encode WriteableBitmap object to a JPEG stream.
            Extensions.SaveJpeg(wb, fileStream, wb.PixelWidth, wb.PixelHeight, 0, 85);
            fileStream.Close();
        }
    }
    catch (Exception ex)
    {
        //Exception handle appropriately for your app  
    }
    

    [Reference]

    0 讨论(0)
  • 2020-12-11 08:37

    In my opinion best way to use native implementation like this (Wrapping Begin/End asynchronous API):

    var url = new Uri(UriString, UriKind.Absolute);
    var fileName = Path.GetFileName(url.LocalPath);
    
    var w = WebRequest.CreateHttp(url);
    var response = await Task.Factory.FromAsync<WebResponse>(w.BeginGetResponse, w.EndGetResponse, null);
    await response.GetResponseStream().CopyToAsync(new FileStream(ApplicationData.Current.LocalFolder.Path + @"\" + fileName, FileMode.CreateNew));
    
    0 讨论(0)
提交回复
热议问题