我正在开发一个Xamarin应用程序,该应用程序将从数据库中检索信息,拍摄/选择照片并将其上传到远程服务器,从远程服务器显示此图像,用户可以通过点击并按下按钮来删除它们。最后一步是将服务器中存储的图像下载到本地设备库中。
这是我当前的按钮单击事件:
private void button_download_image_Clicked(object sender, EventArgs e)
{
Uri image_url_format = new Uri(image_url);
WebClient webClient = new WebClient();
try
{
webClient.DownloadDataAsync(image_url_format);
webClient.DownloadDataCompleted += webClient_DownloadDataCompleted;
}
catch (Exception ex)
{
DisplayAlert("Error", ex.ToString(), "OK");
}
}
webClient_DownloadDataCompleted
方法下面:
private void webClient_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
{
try
{
Uri image_url_format = new Uri(image_url);
byte[] bytes_image = e.Result;
Stream image_stream = new MemoryStream(bytes_image);
string dest_folder= Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads).ToString();
string file_name= Path.GetFileName(image_url_format.LocalPath);
string dest_path= Path.Combine(dest_folder, file_name);
using (var fileStream = new FileStream(dest_path, FileMode.Create, FileAccess.Write))
{
image_stream.CopyTo(fileStream);
}
DisplayAlert("Alert", "Download completed!", "OK");
}
catch (Exception ex)
{
DisplayAlert("Error", ex.ToString(), "OK");
}
}
但是它不起作用,未捕获任何错误,我收到警报,警告我下载已完成。我还授予了internet,write_external_storage和read_external_storage的权限。
另一件事是一段时间后,图像会出现在Download相册下面的图库中,这是正确的。
关于此行为的任何想法吗?
原因
您的函数“触发并忘记”下载内容,然后直接向您显示“下载完成”弹出窗口。原因是您正在以同步方式(DownloadDataAsync
)调用asynchronous
函数...这就是为什么它在弹出后仍会出现在图库中的原因。解决方案
您应该首先阅读:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/然后作为起点,尝试声明事件处理程序异步并在适当的位置使用await关键字:
private async void button_download_image_Clicked(object sender, EventArgs e)
{
Uri image_url_format = new Uri(image_url);
WebClient webClient = new WebClient();
try
{
await webClient.DownloadDataAsync(image_url_format); // This will await the download
...
}
catch (Exception ex)
{
...
}
}
当然,最好完全使用async / await模式来重构另一种方法,但是我想这为您提供了一个很好的起点。快乐编码!