2011-02-05 2 views
5

Я застрял в месте. Я читаю FLV-файл из URL-адреса. Я читаю это в Stream, а затем записываю этот поток в MemoryStream в цикле. Когда код выходит из цикла, я пишу весь MemoryStream в ByteArray, а затем записываю этот ByteArray в локальный файл на своем жестком диске.Чтение потока в поток MemoryStream в нескольких потоках

Поскольку этот flv слишком велик, для обработки в цикле требуется много времени. Я подумываю о чтении оригинального большого потока в MemoryStream в нескольких потоках. Это означает разделение потока на 10 частей и запись этих частей в MemoryStream в нескольких потоках. Как мне это сделать?

Я прикрепляю свою часть кода.

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


       } 

Любая помощь приветствуется Спасибо

+1

Почему, по вашему мнению, несколько пригонков помогут вам здесь? –

+0

Если я могу прочитать этот большой поток для memystream в потоках, я действительно могу ускорить процесс. –

+0

Узким местом в этом случае является время, которое требуется, чтобы прибыть через сеть, а не время, необходимое для его чтения и перемещения в памяти. –

ответ

2

Вы не сможете ускорить загрузку с помощью нескольких потоков. Ограничивающим фактором здесь является не то, как быстро ваш компьютер может обрабатывать данные, а скорее, как быстро данные поступают с сервера.

Вместо того, чтобы пытаться ускорить это, используя несколько потоков, я предлагаю вам создать WebClient, а не WebRequest. Затем вы можете позвонить WebClient.DownloadDataAsync, чтобы загрузить данные в память в фоновом режиме, или позвоните по телефону WebClient.DownloadFileAsync, чтобы загрузить его непосредственно в файл.

Ни один из них не сделает загрузку более быстрой, но они не позволят вашему пользовательскому интерфейсу быть невосприимчивым во время загрузки.

+0

Но как работает многосегментная загрузка? –

+1

В многосегментной загрузке используются запросы GET диапазона HTTP. Он выполняет несколько одновременных запросов (на тот же сервер или зеркала). Существует несколько потоков, каждый из которых загружает разные части файла. Кроме того, есть какая-то задача управления, контролирующая отдельные потоки, и обработка отдельных частей файла вместе, как только будут загружены все сегменты. См. Http://www.codeproject.com/KB/IP/MyDownloader.aspx для примера. –

1

Нитки не помогут вам здесь; вы будете заблокированы IO. Вместо 1 потока, заблокированного в IO, теперь у вас будет несколько потоков, заблокированных в IO. Фактически, во многих случаях разговор с одним и тем же ресурсом (или параллельными, но связанными ресурсами) на нескольких потоках будет уменьшение Производительность ввода-вывода, а также накладные расходы. Потерять: проиграть.

также - большинство потоков не разработано для резьбы; вам понадобится очень сложный координирующий код, чтобы убедиться, что вы собрали поток в правильном порядке и не испортили внутреннее состояние; честно говоря, это не стоит.