我正在开发一个wp7应用程序。我需要从服务器下载一些文件到我的手机。从列表框中选择文件。当试图下载单个项目时,下载工作完美。但是,当我尝试同时下载多个项目时,会发生错误。如何同时下载多个项目?
这是我的下载文件代码。
IList<Item> selectedItems = documents.Where( p => p.IsChecked == true ).ToList();
foreach ( var item in selectedItems )
{
FileDownload objDownload = new FileDownload();
objDownload.FileName = item.Title;
objDownload.Url = item.Link;
objDownload.DocId = item.DocId;
ThreadPool.QueueUserWorkItem( t =>
{
Dispatcher.BeginInvoke( () =>
{
objDownload.DownloadFile();
} );
Thread.Sleep( 0 );
} );
}
这是FileDownload类
中的DownloadFile()方法public void DownloadFile()
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create( Url );
request.AllowReadStreamBuffering = false;
request.BeginGetResponse( new AsyncCallback( DownloadFileData ), request );
}
private void DownloadFileData( IAsyncResult result )
{
try
{
AddToDownloadList();
IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication();
string fileName = "DownloadedFiles\\" + FileName;
if ( !isf.DirectoryExists( "DownloadedFiles" ) )
isf.CreateDirectory( "DownloadedFiles" );
if ( !isf.FileExists( fileName ) )
{
IsolatedStorageFileStream streamToWriteTo = new IsolatedStorageFileStream( fileName, FileMode.Create, isf);
HttpWebRequest request = (HttpWebRequest)result.AsyncState;
HttpWebResponse response = (HttpWebResponse)request.EndGetResponse( result );
Stream str = response.GetResponseStream();
byte [ ] data = new byte [ 16 * 1024 ];
int read;
long totalValue = response.ContentLength;
while ( ( read = str.Read( data, 0, data.Length ) ) > 0 )
{
streamToWriteTo.Write( data, 0, read );
}
string file = streamToWriteTo.ToString();
streamToWriteTo.Close();
}
OfflineStatus = true;
}
catch ( Exception ex )
{
OfflineStatus = false;
}
}
如何使用多线程下载文件。
答案 0 :(得分:3)
您的代码存在一些问题:
你必须关闭/处置商店。最好的实践是使用using语句
使用(var store = IsolatedStorageFile.GetUserStoreForApplication()) { //任务 }
您无法获得使用多线程下载内容的任何性能* - 连接是瓶颈,而不是每秒CPU周期。
如果你有一个多线程应用程序为同一个位置执行IO,如果(!isf.DirectoryExists(“DownloadedFiles”))将无效。你有竞争条件。如果一个线程开始创建dir并且第二个线程在第一个完成之前检查dir怎么办?
不要使用catch吞下异常(Exception ex)。通常情况下,例外情况都包含有关问题的信息。
我会使用与this one类似的解决方案解决此问题。
*多线程应用程序往往是不确定的,下载可能会更快,但在这种情况下,很可能,它会更慢。
答案 1 :(得分:1)
你正在覆盖你的循环中的objDownload对象,破坏了之前的引用。 创建FileDownload列表并添加每个文件以保持独立。
答案 2 :(得分:1)
rob是正确的,但你完全没有使用ThreadPool.QueueUserWorkItem
+ Dispatcher.BeginInvoke
,因为WebRequest.BeginGetResponse是异步和非阻塞的。您当前的代码移动到后台线程,然后移动到UI线程,然后执行在后台线程上返回的异步HTTP操作(这非常疯狂)。
旁注:您下载的文件是否较大(例如&gt; 1mb)?如果是这样,您应该使用Background File Transfers - 即使应用程序未运行,它们也会继续下载。