简体   繁体   中英

How to use multithreading in wp7?

I am developing a wp7 application. I need to download some files from a server to my phone. The files are selected from a listbox. When trying to download a single item the download works perfectly. But when I am trying to download more than one item simultaneously there is an error occurs. How can I download more than one item simultaneously?

here is my code for download files.

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 );
   } );
}

and here is the DownloadFile() method in FileDownload class

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;
    }
}

How can I use multithreading for downloading the files.

There are a few problem with your code:

  • you have to close/dispose the store. The best pratice is to use a using statement

    using (var store = IsolatedStorageFile.GetUserStoreForApplication()) { // task }

  • You won't gain any performance of downloading stuff using multiple threads* - the connection is the bottleneck not the CPU cycles per second.

  • If you have a multithreaded app that does IO for the same location simple if ( !isf.DirectoryExists( "DownloadedFiles" ) ) won't work. You have a race condition. What if one thread starts creating the dir and second thread checks the dir before first one finished?

  • Do not swallow exception with catch ( Exception ex ). Very often the exception has the information about the problem.

I would solve this problem using a similar solution to this one .

*Multithreaded apps tend to be indeterministic, is it possible that download will be faster, but in this case, most likely, it will be slower.

you are overwriting your objDownload object in your loop, destroying the previous reference. create List of FileDownload and add each on to keep separate.

rob is correct with regards to your objDownload, but your use of ThreadPool.QueueUserWorkItem + Dispatcher.BeginInvoke are completely unnecessary as WebRequest.BeginGetResponse is asynchronous and non-blocking. Your current code moves to a background thread, then to the UI thread, and then performs an async HTTP operation that returns on a background thread (which is pretty crazy).

Side note: are the files you are downloading large (eg. > 1mb)? If so, you should be using Background File Transfers - they will continue to download even when your application is not running.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM