[英]Cannot update Progress Bar when download in google drive in C#
我正在使用Google Drive V3 API。 下載文件時我嘗試更新進度,但似乎無法正常工作。
我使用Dispatcher.BeginInvoke()更新了progressbar的值。
當我在progressBar.Value上調試時,它沒有跳到這一行: progressBar.Value = Convert.ToDouble(progress.BytesDownloaded * 100 / fileSize);
我已經在Google和stackoverflow中進行搜索,但找不到解決方案。
請幫忙。 謝謝高級!
MainWindow.xaml
<Window x:Class="DownloadProgress.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:DownloadProgress"
mc:Ignorable="d"
Title="MainWindow" Height="150" Width="400">
<StackPanel>
<ProgressBar Height="30" Margin="10" Name="progressBar"/>
<Button Height="30" Content="Downloads" Margin="10" Click="StartDownload"/>
</StackPanel>
</Window>
MainWindow.xaml.cs
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void StartDownload(object sender, RoutedEventArgs e)
{
string[] Scopes = { DriveService.Scope.DriveReadonly };
DriveService driveService = AuthenticateServiceAccount(@"C:\Users\210636\Downloads\licensemanage-cf129668e7ad.json", Scopes);
FilesResource.ListRequest listRequest = driveService.Files.List();
listRequest.Q = "'1Rl6E1sLkMdW0iRpfdrOzdF4C_U6lfZhu' in parents";
listRequest.PageSize = 10;
listRequest.Fields = "nextPageToken, files(id, name, size)";
IList<Google.Apis.Drive.v3.Data.File> files = listRequest.Execute().Files;
var fileId = "1QETWTnkIp9q6O35Rm99qC6LsJ4Gdg3I5";
var request = driveService.Files.Get(fileId);
request.Fields = "id, name, size";
var file = request.Execute();
long? fileSize = file.Size;
string f = driveService.Files.Get(fileId).Execute().Name;
var streamDownload = new MemoryStream();
progressBar.Minimum = 0;
progressBar.Maximum = 100;
progressBar.Value = 50;
request.MediaDownloader.ProgressChanged += (IDownloadProgress progress) =>
{
switch (progress.Status)
{
case DownloadStatus.Downloading:
{
Dispatcher.BeginInvoke(new Action(() =>
{
progressBar.Value = Convert.ToDouble(progress.BytesDownloaded * 100 / fileSize);
}));
break;
}
case DownloadStatus.Completed:
{
Console.WriteLine("Download complete.");
using (FileStream fs = new FileStream("downloaded.zip", FileMode.OpenOrCreate))
{
streamDownload.WriteTo(fs);
fs.Flush();
}
break;
}
case DownloadStatus.Failed:
{
break;
}
}
};
request.Download(streamDownload);
}
public static DriveService AuthenticateServiceAccount(string serviceAccountCredentialFilePath, string[] scopes)
{
GoogleCredential credential;
using (var stream = new FileStream(serviceAccountCredentialFilePath, FileMode.Open, FileAccess.Read))
{
credential = GoogleCredential.FromStream(stream)
.CreateScoped(scopes);
}
// Create the Analytics service.
return new DriveService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Drive Service account Authentication Sample",
});
}
}
request.Download(streamDownload);
正在阻止UI線程。 下載應該是async
。 我也強烈建議使用Progress<T>
向UI報告進度: 4.5中的異步:在異步API中啟用進度和取消 。
MainWindow.xaml.cs
// Asynchronous event handler
private async void StartDownloadAsync(object sender, RoutedEventArgs e)
{
...
var fileId = "1QETWTnkIp9q6O35Rm99qC6LsJ4Gdg3I5";
progressBar.Minimum = 0;
progressBar.Maximum = 100;
progressBar.Value = 50;
// Creating an instance of Progress<T> captures the current
// SynchronizationContext (UI context) to prevent cross threading when updating the ProgressBar
IProgress<double> progressReporter =
new Progress<double>(value => progressBar.Value = value);
await DownloadAsync(progressReporter, fileId);
}
private async Task DownloadAsync(progressReporter, string fileId)
{
var streamDownload = new MemoryStream();
var request = driveService.Files.Get(fileId);
var file = request.Execute();
long? fileSize = file.Size;
// Report progress to UI via the captured UI's SynchronizationContext using IProgress<T>
request.MediaDownloader.ProgressChanged +=
(progress) => ReportProgress(progress, progressReporter, fileSize, streamDownload);
// Execute download asynchronous
await Task.Run(() => request.Download(streamDownload));
}
private void ReportProgress(IDownloadProgress progress, IProgress<double> progressReporter, long? fileSize, MemoryStream streamDownload)
{
switch (progress.Status)
{
case DownloadStatus.Downloading:
{
double progressValue = Convert.ToDouble(progress.BytesDownloaded * 100 / fileSize);
// Update the ProgressBar on the UI thread
progressReporter.Report(progressValue);
break;
}
case DownloadStatus.Completed:
{
Console.WriteLine("Download complete.");
using (FileStream fs = new FileStream("downloaded.zip", FileMode.OpenOrCreate))
{
streamDownload.WriteTo(fs);
fs.Flush();
}
break;
}
case DownloadStatus.Failed:
{
break;
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.