Низкая производительность при чтении из потока .NET - PullRequest
3 голосов
/ 25 июля 2010

У меня есть система мониторинга, и я хочу сохранить снимок с камеры при срабатывании тревоги. Я перепробовал много способов сделать это ... и все работает нормально, снимок потока с камеры, а затем сохранить его в формате JPG на ПК ... изображение (формат jpg, 1280 * 1024,140KB). Но моя проблема в производительности приложения ... Приложению требуется около 20 ~ 30 секунд для чтения пара, это неприемлемо, потому что метод будет вызываться каждые 2 секунды. Мне нужно знать, что не так с этим кодом и как я могу получить его намного быстрее, чем этот. ? Спасибо заранее Код:

string sourceURL = "http://192.168.0.211/cgi-bin/cmd/encoder?SNAPSHOT";
byte[] buffer = new byte[200000];
int read, total = 0;
WebRequest req = (WebRequest)WebRequest.Create(sourceURL);
req.Credentials = new NetworkCredential("admin", "123456");
WebResponse resp = req.GetResponse();
Stream stream = resp.GetResponseStream();
while ((read = stream.Read(buffer, total, 1000)) != 0)
  {
      total += read;
  }
Bitmap bmp = (Bitmap)Bitmap.FromStream(new MemoryStream(buffer, 0,total));
string path = JPGName.Text+".jpg";
bmp.Save(path);

Ответы [ 4 ]

3 голосов
/ 25 июля 2010

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

Технически, вы можете создать битовую карту без сохранения в буфере памяти.во-первых, или если вам не нужно отображать изображение, вы можете сохранить необработанные данные, даже не создавая растровое изображение, но это не поможет с точки зрения повышения производительности за несколько секунд.Вы проверили, сколько времени требуется для загрузки изображения с этого URL с помощью браузера, wget, curl или любого другого инструмента, потому что я подозреваю, что что-то происходит с источником кодирования.ваши ресурсы;закройте поток правильно.Это может вызвать проблему, если вы будете регулярно вызывать этот метод, потому что .NET будет открывать только несколько соединений с одним и тем же хостом в любой точке.

// Make sure the stream gets closed once we're done with it
using (Stream stream = resp.GetResponseStream())
{
    // A larger buffer size would be benefitial, but it's not going
    // to make a significant difference.
    while ((read = stream.Read(buffer, total, 1000)) != 0)
    {
        total += read;
    }
}
1 голос
/ 25 июля 2010

Попробуйте прочитать большие фрагменты данных, чем 1000 байтов за раз.Я не вижу проблем с, например,

read = stream.Read(buffer, 0, buffer.Length);
1 голос
/ 25 июля 2010

Я не могу попробовать сетевое поведение потока WebResponse, но вы обрабатываете поток дважды (один раз в цикле и один раз с потоком памяти).

Не думаю, что в этом вся проблема, но яЯ бы попробовал:

     string sourceURL = "http://192.168.0.211/cgi-bin/cmd/encoder?SNAPSHOT";
     WebRequest req = (WebRequest)WebRequest.Create(sourceURL);
     req.Credentials = new NetworkCredential("admin", "123456");
     WebResponse resp = req.GetResponse();
     Stream stream = resp.GetResponseStream();
     Bitmap bmp = (Bitmap)Bitmap.FromStream(stream);
     string path = JPGName.Text + ".jpg";
     bmp.Save(path);
0 голосов
/ 25 июля 2010

Попробуйте загрузить этот файл.

using(WebClient webClient = new WebClient())
{
    webClient.DownloadFile("http://192.168.0.211/cgi-bin/cmd/encoder?SNAPSHOT", "c:\\Temp\myPic.jpg");
}

Вы можете использовать DateTime для нанесения уникальной отметки на снимок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...