我在使用ui更新从服务器下载多个图像时遇到问题。问题是我在服务器上有壁纸文件夹,我想下载图像,我运行后台工作程序下载图像并更新我的UI,我的UI更新将在我的所有图像下载后完成(BackgroundWorker_Completed)。但是我希望每次下载一个图像文件夹时都会更新我的UI,如下图所示。
在上面给出的示例中,每个文件夹包含多个图像,例如电影,游戏,印度等,并且它们具有其所属类别的图像,例如,在电影中,他们的文件夹是Man Of Steel,Priest等。现在,当我下载我的图像时,他们应该在UI上可见,每次下载都不是最后一次。下载壁纸的代码如下:
下载图片的后台工作程序代码
void worker_DoWork(object sender, DoWorkEventArgs e)
{
try
{
DataSet dsFile = Global.ReadConfig;
XDocument xDoc = XDocument.Load(dsFile.Tables[0].Rows[0][8].ToString());
string s = xDoc.Root.Name.ToString();
var countNode = xDoc.Root.Elements().Count();
for (int i = 0; i < countNode; i++)
{
XNode childNode = xDoc.Root.Nodes().ElementAt(i);
XElement ele = (XElement)childNode;
string path = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\Wallpaper\\" + ele.Name;
var movieList = from a in xDoc.Root.Descendants(ele.Name).Elements()
select a;
foreach (var a in movieList)
{
string newpath = path + "\\" + a.Value;
DirectoryInfo di = new DirectoryInfo(newpath);
if (!di.Exists)
{
DirectoryInfo dinew = Directory.CreateDirectory(newpath);
filedownload(dsFile.Tables[0].Rows[0][1].ToString() + "/Wallpaper/" + ele.Name + "/" + dinew.Name + "/", newpath + "\\");
}
}
//new DesktopThemes.App_Page.MainWindow().getWallLink(ele.Name.LocalName);
}
}
catch
{
}
}
后台工作人员已完成在UI上显示图片
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
string N = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + @"\Wallpaper\" ;
Random random = new Random();
List<String> backimage = new List<String>();
DirectoryInfo diback = new DirectoryInfo(N);
// diback.GetFiles();
Directory.GetFiles(N, "*.*", SearchOption.AllDirectories);
foreach (var imagename in diback.GetFiles("*.jpg", SearchOption.AllDirectories))
{
backimage.Add(imagename.Directory + "\\" + imagename.Name);
}
try
{
Image image = new Image();
Uri add = new Uri(backimage[random.Next(0, backimage.Count - 1)]);
image.Source = new BitmapImage(add);
pnlBackground.Source = image.Source;
this.Photos.Path = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + @"Wallpaper\";
}
catch (Exception ex)
{
}
}
代码用于下载从后台工作人员调用的图像
public static void filedownload(String url, string downloadlocation)
{
FtpWebRequest ftpRequest = (FtpWebRequest)WebRequest.Create(url);
ftpRequest.Credentials = new NetworkCredential(@username, @password);
ftpRequest.Method = WebRequestMethods.Ftp.ListDirectory;
FtpWebResponse response = (FtpWebResponse)ftpRequest.GetResponse();
StreamReader streamReader = new StreamReader(response.GetResponseStream());
List<string> directories = new List<string>();
string line = streamReader.ReadLine();
while (!string.IsNullOrEmpty(line))
{
directories.Add(line);
line = streamReader.ReadLine();
}
streamReader.Close();
using (WebClient ftpClient = new WebClient())
{
ftpClient.Credentials = new System.Net.NetworkCredential(@username, @password);
for (int i = 0; i <= directories.Count - 1; i++)
{
if (directories[i].Contains("."))
{
string path = url + directories[i].ToString();
string trnsfrpth = downloadlocation + directories[i].ToString(); if (!new System.IO.FileInfo(trnsfrpth).Exists)
{
ftpClient.DownloadFile(path, trnsfrpth);
}
}
}
}
}
答案 0 :(得分:3)
要了解如何异步下载大量图像,同时在ListBox中显示它们,请查看以下简化视图模型,该模型为所有下载的图像声明了一个集合属性,并{{1执行下载的方法。
下载是异步的,因为该方法调用(并等待)异步async
方法。
为了演示,它从HttpClient.GetByteArrayAsync()
下载256(地图图块)图像。
openstreetmap.org
您可以设置您的MainWindow public class ViewModel
{
public ObservableCollection<ImageSource> Images { get; private set; }
= new ObservableCollection<ImageSource>();
public async Task DownloadImages()
{
var httpClient = new HttpClient();
for (int y = 0; y < 16; y++)
{
for (int x = 0; x < 16; x++)
{
var url = string.Format(
"http://tile.openstreetmap.org/4/{0}/{1}.png", x, y);
// the await here makes the download asynchronous
var buffer = await httpClient.GetByteArrayAsync(url);
using (var stream = new MemoryStream(buffer))
{
Images.Add(BitmapFrame.Create(
stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad));
}
}
}
}
}
并在DataContext
事件处理程序中开始下载,如下所示:
Loaded
最后,ListBox的XAML可能如下所示:
public MainWindow()
{
InitializeComponent();
var viewModel = new ViewModel();
DataContext = viewModel;
Loaded += async (s, e) => await viewModel.DownloadImages();
}