Чтение потока в MemoryStream в нескольких потоках

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

Поскольку этот 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();
                    }  


                }

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


person sumit_programmer    schedule 05.02.2011    source источник
comment
Почему вы думаете, что несколько потоков помогут вам здесь?   -  person Itay Karo    schedule 05.02.2011
comment
Если я смогу прочитать этот большой поток в memorystream в потоках, я действительно смогу ускорить процесс.   -  person sumit_programmer    schedule 05.02.2011
comment
Узким местом в этом случае является время, необходимое для поступления по сети, а не время, необходимое для его чтения и перемещения в памяти.   -  person Itay Karo    schedule 06.02.2011


Ответы (2)


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

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

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

person Jim Mischel    schedule 05.02.2011
comment
Многосегментная загрузка использует GET-запросы диапазона HTTP. Он делает несколько одновременных запросов (к одному и тому же серверу или к зеркалам). Работает несколько потоков, каждый из которых загружает разные части файла. Кроме того, существует своего рода задача управления, контролирующая отдельные потоки и обрабатывающая объединение отдельных частей файла после загрузки всех сегментов. Пример см. на странице codeproject.com/KB/IP/MyDownloader.aspx. - person Jim Mischel; 05.02.2011

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

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

person Marc Gravell    schedule 05.02.2011