Очень простой образец.Я уверен, что есть место для оптимизаций, и вы можете сделать из него отдельный класс, который сможет обрабатывать многочисленные запросы, но, по крайней мере, он будет работать, и вы сможете настроить его для своих нужд.Также обратите внимание, что этот пример создает изображение каждый раз, когда мы сообщаем о прогрессе, вам следует избегать его!Делайте изображение примерно каждые 5% или около того, чтобы избежать больших накладных расходов.
Xaml:
<Window x:Class="ScrollViewerTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<StackPanel>
<TextBlock Text="{Binding Path=Progress, StringFormat=Progress: {0}}" />
<Image Source="{Binding Path=Image}" />
</StackPanel>
</Window>
Кодовый код:
public partial class MainWindow : Window, INotifyPropertyChanged
{
#region Public Properties
private int _progress;
public int Progress
{
get { return _progress; }
set
{
if (_progress != value)
{
_progress = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("Progress"));
}
}
}
private BitmapImage image;
public BitmapImage Image
{
get { return image; }
set
{
if (image != value)
{
image = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("Image"));
}
}
}
#endregion
BackgroundWorker worker = new BackgroundWorker();
public MainWindow()
{
InitializeComponent();
worker.DoWork += backgroundWorker1_DoWork;
worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
worker.WorkerReportsProgress = true;
worker.RunWorkerAsync(@"http://Tools.CentralShooters.co.nz/Images/ProgressiveSample1.jpg");
}
// This function is based on code from
// http://devtoolshed.com/content/c-download-file-progress-bar
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
// the URL to download the file from
string sUrlToReadFileFrom = e.Argument as string;
// first, we need to get the exact size (in bytes) of the file we are downloading
Uri url = new Uri(sUrlToReadFileFrom);
System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url);
System.Net.HttpWebResponse response = (System.Net.HttpWebResponse)request.GetResponse();
response.Close();
// gets the size of the file in bytes
Int64 iSize = response.ContentLength;
// keeps track of the total bytes downloaded so we can update the progress bar
Int64 iRunningByteTotal = 0;
// use the webclient object to download the file
using (System.Net.WebClient client = new System.Net.WebClient())
{
// open the file at the remote URL for reading
using (System.IO.Stream streamRemote = client.OpenRead(new Uri(sUrlToReadFileFrom)))
{
using (Stream streamLocal = new MemoryStream((int)iSize))
{
// loop the stream and get the file into the byte buffer
int iByteSize = 0;
byte[] byteBuffer = new byte[iSize];
while ((iByteSize = streamRemote.Read(byteBuffer, 0, byteBuffer.Length)) > 0)
{
// write the bytes to the file system at the file path specified
streamLocal.Write(byteBuffer, 0, iByteSize);
iRunningByteTotal += iByteSize;
// calculate the progress out of a base "100"
double dIndex = (double)(iRunningByteTotal);
double dTotal = (double)byteBuffer.Length;
double dProgressPercentage = (dIndex / dTotal);
int iProgressPercentage = (int)(dProgressPercentage * 100);
// update the progress bar, and we pass our MemoryStream,
// so we can use it in the progress changed event handler
worker.ReportProgress(iProgressPercentage, streamLocal);
}
// clean up the file stream
streamLocal.Close();
}
// close the connection to the remote server
streamRemote.Close();
}
}
}
void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
Dispatcher.BeginInvoke(
System.Windows.Threading.DispatcherPriority.Normal,
new Action(delegate()
{
MemoryStream stream = e.UserState as MemoryStream;
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.StreamSource = new MemoryStream(stream.ToArray());
bi.EndInit();
this.Progress = e.ProgressPercentage;
this.Image = bi;
}
));
}
public event PropertyChangedEventHandler PropertyChanged;
}