我在WPF应用上使用VS2010。 我无法使用 async
功能。
基本上我需要加载两个图像,下载图像后需要打印它们。
我需要管理两个图像的下载。怎么做到这一点?
var bitmap = new BitmapImage(new Uri("http://abcd.com/logo.png"));
var bitmapB = new BitmapImage(new Uri("http://abcd.com/logoB.png"));
if (!bitmap.IsDownloading)
{
// print immediately code here
}
else
{
bitmap.DownloadCompleted += (o, e) =>
{
// print when download completed
};
}
if (!bitmapB.IsDownloading)
{
// print immediately
}
else
{
bitmapB.DownloadCompleted += (o, e) =>
{
// print when download completed
};
}
答案 0 :(得分:2)
这听起来像你真正想要的是WebClient
Class。您可以使用其多种方法将图像作为文件或byte
集合下载。最好的部分是您也可以异步执行此操作,因此它将自动发生在后台线程上。
使用这些异步方法时,需要处理相关的Download...Completed
事件以检索结果。来自MSDN上的DownloadStringCompletedEventHandler
Event页:
public static void DownLoadFileInBackground2 (string address)
{
WebClient client = new WebClient ();
Uri uri = new Uri(address);
// Specify that the DownloadFileCallback method gets called
// when the download completes.
client.DownloadFileCompleted += new AsyncCompletedEventHandler(
DownloadFileCallback2);
// Specify a progress notification handler.
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(
DownloadProgressCallback);
client.DownloadFileAsync (uri, "serverdata.txt");
}
有关详细信息,请查看MSDN网站上的WebClient.DownloadDataAsync
Method和WebClient.DownloadFileAsync
Method页面。
答案 1 :(得分:1)
类似下面的代码应该为可变数量的图像执行任务。它在调用UI线程中的PrintImages
方法之前,在ThreadPool线程中按顺序下载所有图像。请注意,下载后每个图像都被冻结(image.Freeze()
),以使其可以跨线程访问。
private void DownloadAndPrintImagesAsync(IEnumerable<string> urls)
{
ThreadPool.QueueUserWorkItem(o =>
{
var images = urls.Select(url => DownloadImage(url));
Dispatcher.Invoke(new Action(() => PrintImages(images)));
});
}
private BitmapImage DownloadImage(string url)
{
var buffer = new WebClient().DownloadData(url);
var image = new BitmapImage();
using (var stream = new MemoryStream(buffer))
{
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.StreamSource = stream;
image.EndInit();
}
image.Freeze();
return image;
}
private void PrintImages(IEnumerable<BitmapImage> images)
{
// print here
}
您可以通过并行发出多个下载来改善这一点,但这会使代码复杂化。在打印之前,您必须等待所有异步下载完成。
更新:根据Sheridan提供的建议,您可以像这样修改DownloadAndPrintImagesAsync
方法:
private List<BitmapImage> images = new List<BitmapImage>();
private void DownloadAndPrintImagesAsync(IEnumerable<string> urls)
{
foreach (var url in urls)
{
var webClient = new WebClient();
webClient.DownloadDataCompleted += ImageDownloadCompleted;
webClient.DownloadDataAsync(new Uri(url));
}
}
private void ImageDownloadCompleted(object sender, DownloadDataCompletedEventArgs e)
{
if (!e.Cancelled && e.Error == null)
{
var image = new BitmapImage();
using (var stream = new MemoryStream(e.Result))
{
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.StreamSource = stream;
image.EndInit();
}
images.Add(image);
if (images.Count == 2) // or whatever
{
// print images
}
}
}