2010-06-21 10 views
7

Piszę bibliotekę klasy C#, aby przesyłać duże ilości danych przez automatyzację COM za pomocą IStream. Używa wywołania API CreateStreamOnHGlobal do utworzenia strumienia, a metody z nim związane są dostępne w ramach System.Runtime.InteropServices.COMTypes.IStream.Jaki jest właściwy sposób zarządzania dużymi kanałami IStream?

Moje pytanie brzmi: czy w przypadku przesyłania dużych ilości danych najlepszy jest sposób na kontrolowanie śladu pamięci? Załadowanie 100 MB danych z plików do pamięci wydaje się marnotrawstwem, a aplikacja kliencka musiałaby poczekać, aż proces ten zostanie ukończony przed pobraniem czegokolwiek.

Mój plan polegał na stworzeniu strumienia o rozsądnych rozmiarach i napisaniu do niego wiele razy. Przed napisaniem następnej porcji danych odszukaj początek i nadpisz od początku. Czy podążam tą drogą we właściwy sposób i czy istnieje lepsza metoda rozwiązania tego problemu?

+0

Skąd pochodzą dane? Rzadko trzeba przechowywać * wszystko * w pamięci. Z pewnością możesz po prostu przeczytać ją w implementacji metody Read()? –

+0

Z różnych źródeł, w tym tabel db i plików tekstowych. Kod biblioteki analizuje dane w tablicy bajtów i przesyła je do strumienia. Mogę pisać, czytać/pisać w małych porcjach, to nie jest problem. Problem polega na tym, że jak będę pisał na końcu strumienia, będzie on stale się powiększał, prawda? – polara

+2

Prawdopodobnie najlepiej piszesz własną klasę, która implementuje interfejs IStream, wtedy możesz obsłużyć wywołania metody Read i załadować dane na żądanie, po przeczytaniu nie ma już potrzeby utrzymywania tych danych (zakładając, że nie pozwalasz IStream, aby był widoczny). – tyranid

Odpowiedz

0

W przypadku tymczasowego lokalnego przechowywania dużych ilości danych plik mapowany w pamięci jest zazwyczaj dobrym pomysłem. Przekazuje odpowiedzialność za zarządzanie pamięcią na system Windows, który najlepiej wie, jak to zrobić. Jeśli nie określisz pliku, zostanie on odwzorowany na plik stronicowania i nigdy nie dojdzie do dysku fizycznego, chyba że stanie się to konieczne.

Jeśli używasz .NET 4.0, masz managed API do plików mapowanych w pamięci.

1

Czy możesz spojrzeć na ten artykuł z microsoft o dużych danych i przesyłania strumieniowego. W jednym z moich projektów przekazujemy ten sam strumień do klienta i ponieważ nigdy nie robimy buforowania i utrzymujemy go jako strumień, dopóki klient go nie pobierze (przez strumień odpowiedzi dla sieci) lub strumień plików na serwerze. aplikacji Windows, mogliśmy zostawić na serwerze bardzo mniejszy ślad pamięci.

Spróbuj sprawdzić, czy funkcje WCF i TransferMode = Streamed połączone z kodowaniem MTOM pomagają spełnić Twoje wymagania.

dużych danych i strumieniowe => http://msdn.microsoft.com/en-us/library/ms733742.aspx

0

każdego strumienia realies wdrożeniowe w buforze. Przez większość czasu będziesz mieć 100% kontroli nad rozmiarem bufora. Możesz dostosować rozmiar bufora, aby dostroić wydajność względem wykorzystania pamięci. Jeśli nie otwierają setki strumieniu jednocześnie sugeruję być hojny wielkości strumienia tak duży, jak to możliwe:

var readStream = new System.IO.File.OpenRead (sourceFilePath); var writeStream = new System.Io.File.Create (destinationFile);

bajt [] bufor = nowe bajty [bufferSize]; int readLength; while ((readLength = readStream.Read (0,0, bufferSize))> 0) { writeStream.Write (bufor, 0, odczytana długość); }

writeStream.Close(); readStream.Close();

1

Rozważ użycie pliku utworzonego z atrybutami FILE_ATTRIBUTE_TEMPORARY i FILE_FLAG_DELETE_ON_CLOSE. Napisz tam coś tam. Windows spróbuje zachować go w pamięci podręcznej dysku, chyba że skończy się pamięć. Zostanie ona autodestrukcji po zamknięciu klamki lub po zakończeniu programu (lub awarii!). Dowiedziałem się o tym here.

0

Podczas wysyłania dużych wiadomości za pomocą Windows Communication Foundation (WCF) często pożądane jest ograniczenie ilości pamięci używanej do buforowania tych wiadomości. Jednym z możliwych rozwiązań jest strumieniowanie treści wiadomości (zakładając, że większość danych znajduje się w ciele). Jednak niektóre protokoły wymagają buforowania całej wiadomości. Niezawodne przesyłanie wiadomości i bezpieczeństwo to dwa takie przykłady.

Innym możliwym rozwiązaniem jest podzielenie się duże wiadomości na mniejsze kawałki zwane wiadomości, wysłać te kawałki jeden kawałek na raz, i odtworzyć dużą wiadomość po stronie odbiorczej. Sama aplikacja mogłaby to zrobić, chrupiąc i usuwając fragmenty lub może to zrobić za pomocą niestandardowego kanału. Przykład kanału chunkingu pokazuje, w jaki sposób niestandardowy protokół lub kanał warstwowy może być używany do robienia kawałków i odłupywania dowolnie dużych wiadomości.

próbki umieszczono dostępna do pobrania http://msdn.microsoft.com/en-us/library/aa717050.aspx

Powiązane problemy