Чтение потока в MemoryStream в нескольких потоках - PullRequest
5 голосов
/ 05 февраля 2011

Я застрял в одном месте. Я читаю 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();
                    }  


                }

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

Ответы [ 2 ]

2 голосов
/ 05 февраля 2011

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

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

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

1 голос
/ 05 февраля 2011

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

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

...