Próbuję uzyskać zdjęcia z kamer internetowych. Istnieje usługa sieciowa php-python, która pobiera zdjęcia z kamer internetowych i udostępnia je: wyświetla obraz taki jak http://ip/jpeg/camera=1
.
private HttpWebRequest request;
private HttpWebResponse response;
private CookieContainer container;
private Uri uri;
private string _user;
private string _pass;
private string _ip;
//Login code as seen in the previous section should be here
//GetImages is meant to run as a separate thread
private void GetImages(string camNo)
{
//create the GET request for the JPEG snapshot (found at /jpeg on the IP Camera)
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://" + deviceIP + "/jpeg/camera"+camNo);
request.Method = "GET";
request.ContentType = "application/x-www-form-urlencoded";
request.CookieContainer = container;
//attempt to get a response from the IP110, event if error
try
{
response = (HttpWebResponse)request.GetResponse();
}
catch (WebException e)
{
ConnectionError(new ConnectionErrorEventArgs(e.Message));
}
//Get the stream containing the JPEG image.
Stream stream = response.GetResponseStream();
//Read the stream to memory.
byte[] buffer = new byte[100000];
int read, total = 0;
while ((read = stream.Read(buffer, total, 1000)) != 0)
{
total += read;
}
//create a BMP image from the stream
Bitmap bmp = (Bitmap)Bitmap.FromStream(new MemoryStream(buffer, 0, total));
//send the bmp image to where you would like to display it.
}
... następnie przechowuję tę bitmapę jako jpeg w folderze. Mój problem zaczyna się tutaj; Chcę przeprowadzić ten proces tak szybko, jak to możliwe. Chcę robić zdjęcia z 50 kamerek używając tego kodu i przechowywać jako jpeg, i ma to być szybkie - to znaczy co 10 sekund muszę pobierać nowe zdjęcia z 50 kamer.
Użyłem timecontrol i dałem mu 500 ms co 500 ms program używał tego kodu powyżej numeru kamery i zapisywał jpeg, ale działa jeden po drugim, więc wydajność spada!
50ms x 500cams = 25000 ms (25s), jeśli ustawię interwał timera na 100 ms zatrzymanie programu. Kiedy używam powyższego kodu, otrzymuję bitmapę bmp w 200 ms, ale gdy próbuje pisać jako jpeg na dysku, zajmuje to dużo czasu.
Co mogę zrobić, aby szybciej zapisywać na dysku? Szukałem zmapowanej pamięci - czy to pomoże? Chcę przechowywać jpegi na dysku, ponieważ będę udostępniać te zdjęcia na stronie internetowej i udostępniać je ludziom. Czy mogę używać mapowania pamięci i udostępniać je publicznie za pośrednictwem witryny internetowej?
AKTUALIZACJA: Wykorzystałem również klasę WebClient do prac asynchronicznych, http://www.informit.com/guides/content.aspx?g =dotnet&seqNum=571
Rezultat był taki: uzyskać obraz o długości 300 ms i zapisywać go na dysku około 700 ms. Muszę więc znaleźć rozwiązanie, aby jak najwięcej zapisywać na dysk.
Który jest lepszy? Zapisać zdjęcia na dysk czy wysłać zdjęcia do bazy danych? Próbowałem przechowywać zdjęcia, aby były gotowe do podania, ponieważ na stronie ludzie muszą zobaczyć zaktualizowane zdjęcia. Który jest lepszy dla tysięcy zapytań klientów? Przechowywać je na dysku lub przechowywać w bazie danych jako binarne?
2 odpowiedzi
Kod do pobrania obrazów jest synchroniczny. Sugeruję zmodyfikowanie kodu, aby używał HttpWebRequest.BeginGetResponse()
do pobierania obrazów, jak opisano w ta odpowiedź.
Tak więc, gdy twój (pojedynczy) timer zostanie uruchomiony, rozpocznij asynchroniczne żądania do kamer, a następnie (po ich zakończeniu) wywołanie zwrotne zostanie uruchomione dla każdego zakończonego żądania i możesz zapisać zwrócony obraz.
Jeśli potrzebujesz dalszej optymalizacji, możesz delegować zapisywanie obrazu na dysku w tle ThreadPool
element pracy.
Za każdym razem, gdy potrzebujesz uzyskać odpowiedzi szybciej niż pozwalają na to skumulowane odpowiedzi, musisz wykonać wiele prac jednocześnie, używając więcej niż jednego wątku (ostatnie słowo jest tutaj wskazówką).
W .NET oznacza to albo skonfigurowanie własnej biblioteki wątków, użycie TPL itp.
DODANE: Może to oznaczać, jak wskazano w poniższym komentarzu, używanie wywołań asynchronicznych i umożliwienie frameworkowi niejawnego tworzenia wątków dla ciebie, zamiast samodzielnego kontrolowania ich. W rzeczywistości można korzystać z puli wątków i nadal wybierać asynchroniczną lub synchronizowaną bez kontrolowania liczby utworzonych wątków. Jeśli naprawdę chcesz przejść do sedna, możesz nawet odciążyć wątki do systemu operacyjnego za pomocą obsługi przerwań na poziomie systemu operacyjnego (metoda używana na przykład przez Rubiego przed wersją 1.9, która wprowadziła „prawdziwe” wątki zamiast „ zielone" wątki - tak, TMI).
Odpowiedź nadal pozostaje aktualna, jeśli masz 2 minuty pracy do wykonania i 30 sekund na wykonanie, potrzebujesz rozwiązania wielowątkowego, niezależnie od tego, czy jesteś świadomy, że faktycznie pracujesz w wątkach (tworzenie jawne), czy nie (obsługa tworzenia niejawnego przez framework/OS).
BeginMETHOD
? .NET ma wywołania asynchroniczne dla prawie każdej ważnej metody, po prostu ich użyj!
Podobne pytania
Powiązane pytania
Nowe pytania
c#
C # (wymawiane „patrz ostro”) jest językiem programowania wysokiego poziomu, statycznie typowanym, wieloparadygmatowym opracowanym przez firmę Microsoft. Kod C # zwykle jest przeznaczony dla rodziny narzędzi Microsoft .NET i czasów wykonywania, do których należą między innymi .NET Framework, .NET Core i Xamarin. Użyj tego tagu w przypadku pytań dotyczących kodu napisanego w C # lub C # formalnej specyfikacji.