2011-02-05 17 views
5

Bir yere sıkışmış durumdayım. Bir URL'den bir flv dosyası okuyorum. Bunu bir Akışa okuyorum ve ardından bu Akışı bir döngüde MemoryStream'e yazdım. Kod döngüden çıktığında, tüm MemoryStream'i bir ByteArray'a yazıp bu ByteArray'ı sabit diskimde yerel bir dosyaya yazıyorum.Birden çok iş parçacığında bir MemoryStream akışını okuma

Bu flv çok büyük olduğu için, döngüde işlemek çok zaman alır. Birden fazla iş parçacığında MemoryStream'deki orijinal büyük akışı okumaya çalışıyorum. Bu, Akımı 10 parçaya bölerek ve bu parçaları çoklu threadlarda MemoryStream'e yazmak anlamına gelir. Bunu nasıl yaparım?

Kod parçamı ekliyorum.

//Get a data stream from the url 
       WebRequest req = WebRequest.Create(url); 
       WebResponse response = req.GetResponse(); 
       using (Stream stream = response.GetResponseStream()) 
       { 
        //Download in chuncks 
        byte[] buffer = new byte[1024]; 

        //Get Total Size 
        int dataLength = (int)response.ContentLength; 



        //Download to memory 
        //Note: adjust the streams here to download directly to the hard drive 
        using (MemoryStream memStream = new MemoryStream()) 
        { 
         while (true) 
         { 
          //Try to read the data 
          int bytesRead = stream.Read(buffer, 0, buffer.Length); 

          if (bytesRead == 0) 
          { 
           Application.DoEvents(); 
           break; 
          } 
          else 
          { 
           //Write the downloaded data 
           memStream.Write(buffer, 0, bytesRead); 
          } 
         } 

         //Convert the downloaded stream to a byte array 
         byte[] downloadedData = memStream.ToArray(); 
        } 


       } 

Herhangi bir yardım Teşekkür

+1

Neden birden fazla iş parçacığının burada size yardımcı olacağını düşünüyorsunuz? –

+0

Bu büyük akışı threadlarda memorystream'e okuyabiliyorsam, işlemi gerçekten hızlandırabilirim. –

+0

Buradaki darboğaz, ağ üzerinden ulaşması gereken süreyi ve onu okumak ve hafızaya taşımak için gereken süreyi değil. –

cevap

2

Birden çok iş parçacığı kullanarak indirmeyi hızlandırmak için mümkün olmayacaktır takdir edilmektedir. Burada sınırlayıcı faktör, bilgisayarınızın verileri nasıl işleyebildiği değil, verilerin sunucudan ne kadar hızlı geldiği değil.

Birden çok iş parçacığı kullanarak bunu hızlandırmaya çalışmak yerine, WebRequest yerine WebClient oluşturmanızı öneririz. Ardından, verileri arka planda belleğe indirmek için WebClient.DownloadDataAsync numaralı telefonu arayabilir veya doğrudan bir dosyaya indirmek için WebClient.DownloadFileAsync numaralı telefonu arayabilirsiniz.

Bunlardan biri, daha hızlı indirme yapacak, ancak kullanıcı arabirimi, karşıdan yükleme sırasında yanıt vermemesini engeller.

+0

Ama sonra çoklu program indirme nasıl çalışır? –

+1

Çok bölmeli bir indirme, HTTP aralığı GET isteklerinden yararlanır. Birden çok eşzamanlı istekte bulunur (aynı sunucuya veya aynalara). Her biri dosyanın farklı bölümlerini yükleyen birden çok iş parçacığı vardır. Ayrıca, ayrı bölümlerin kontrol edilmesi ve tüm bölümler indirildikten sonra dosyanın ayrı parçalarının bir araya getirilmesiyle ilgilenen bir yönetim görevi vardır. Örnek için http://www.codeproject.com/KB/IP/MyDownloader.aspx adresine bakın. –

1

Konular burada size yardımcı olmaz; IO'da bloke edileceksiniz. IO'da engellenen 1 iş parçacığı yerine, artık IO'da engellenen birden fazla iş parçacığına sahip olacaksınız. Aslında, birçok durumda aynı konuya (veya paralel ancak ilgili kaynaklara) birden fazla iş parçacığıyla konuşulması, değerini IO çıkışını artırarak iş parçacığı ek yüklerini azaltacaktır. Kaybetmek: kaybetmek.

Ayrıca - çoğu akışlar, iş parçacığı için tasarlanmış değil ; Akışı doğru sırayla yeniden birleştirdiğinizden ve içsel durumu kirletmediğinizden emin olmak için çok karmaşık bir koordinasyon koduna ihtiyacınız olacaktır; Açıkçası, buna değmez.

İlgili konular