2015-12-21 7 views
5

Mam do czynienia z problemem, którego nie jestem w stanie rozwiązać ani znaleźć rozwiązania Google.Usługa Windows: użycie BitmapEncoder lub BitmapDecoder kończy się słowem «Operacja zakończona powodzeniem»

Mam uruchomioną usługę, która ładuje lub zapisuje obrazy i używa klas BitmapEncoder lub BitmapDecoder. Po pewnym czasie (w zależności od tego, jak często zapisuję/ładuję obrazy) serwis odmawia zapisania/załadowania zdjęć. Najpierw Patrz ostrzeżenie w dzienniku zdarzeń z

alokacji sterty udało

google co to znaczy i że ma do czynienia z ograniczoną liczbę obiektów GDI, że usługa Windows ma. Jest możliwa modyfikacja rejestru w celu zwiększenia liczby tych obiektów, ale wydaje mi się, że nie jest to bardzo dobre rozwiązanie, a także nie działa dla mnie.

Mój kod rzuca następujący wyjątek z ślad stosu podczas zapisywania

Error while storing image : System.ComponentModel.Win32Exception (0x80004005): The operation completed successfully 
    at MS.Win32.HwndWrapper..ctor(Int32 classStyle, Int32 style, Int32 exStyle, Int32 x, Int32 y, Int32 width, Int32 height, String name, IntPtr parent, HwndWrapperHook[] hooks) 
    at System.Windows.Threading.Dispatcher..ctor() 
    at System.Windows.Threading.DispatcherObject..ctor() 
    at System.Windows.Media.Imaging.BitmapEncoder..ctor(Boolean isBuiltIn) 
    at Imaging.TiffReadWrite.Save(String filename, Image img) 

i podczas ładowania

Error while loading image : System.ComponentModel.Win32Exception (0x80004005): The operation completed successfully 
    at MS.Win32.HwndWrapper..ctor(Int32 classStyle, Int32 style, Int32 exStyle, Int32 x, Int32 y, Int32 width, Int32 height, String name, IntPtr parent, HwndWrapperHook[] hooks) 
    at System.Windows.Threading.Dispatcher..ctor() 
    at System.Windows.Threading.DispatcherObject..ctor() 
    at System.Windows.Media.Imaging.BitmapDecoder..ctor(Stream bitmapStream, BitmapCreateOptions createOptions, BitmapCacheOption cacheOption, Guid expectedClsId) 
    at Imaging.TiffReadWrite.Load(String filename) 

mojego kodu do zapisywania obrazów wygląda następująco:

public static void Save(string filename, BitmapSource img) 
{ 
    using (FileStream stream = new FileStream(filename, FileMode.Create)) 
    { 
     TiffBitmapEncoder encoder = new TiffBitmapEncoder(); 
     encoder.Compression = TiffCompressOption.None; 

     BitmapFrame frm = BitmapFrame.Create(img); 

     encoder.Frames.Add(frm); 
     encoder.Save(stream); 
    } 
} 

i do ładowania obrazów wygląda tak:

public static BitmapSource Load(string filename) 
{ 
    BitmapSource resultImage = null; 

    using (Stream imSource = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read)) 
    { 
     var decoder = new TiffBitmapDecoder(imSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default); 
     resultImage = decoder.Frames[0]; 
    } 
    return resultImage; 
} 

Usługa odmawia zapisania/załadowania zdjęć. Mogę spróbować/wychwycić ten wyjątek, aby usługa mogła nadal działać, ale nie można zapisać ani załadować żadnych obrazów. Czasami po pierwszym wystąpieniu tego wyjątku można zapisać/załadować kilka obrazów i po pewnym czasie nie jest wykonywane zapisywanie/ładowanie.

Jedynym sposobem obejścia tego problemu nie jest uruchomienie tego kodu w usłudze, ale w aplikacji. Wtedy działa dobrze, ale to nie jest rozwiązanie, którego szukam. Jeśli ktoś ma jakąś lepszą sugestię, proszę dać mi znać.

Istnieje kilka podobnych postów (ślad stosu wyjątku jest mniej więcej taka sama), które w rzeczywistości nie jest rozwiązany:

+0

Cóż, to całkiem bezużyteczny komunikat wyjątku. Usługi działają w sesji 0, ma celowo małą stertę pulpitu. To sprawia, że ​​bardziej prawdopodobne jest, że CreateWindowEx() zawiedzie. Może to być inna usługa, która nieuczciwie się z nią dzieli. Lub twój, licznik "Obiekty użytkownika" w Menedżerze zadań jest twoim pierwszym diagnostycznym. Ryzykujesz również, że GC nie gromadzi się wystarczająco często, możesz potrzebować pomocy, wywołując GC.Collect() samodzielnie każdą bitmapę N. Fakt, że nie ma znaczącego kodu błędu, wskazuje jednak na problem środowiskowy. –

+0

Dziękuję za odpowiedź. Wiem, że jest niejasna i dlatego nie jestem w stanie jej rozwiązać. Sprawdzam Menedżera zadań i użyłem dheapmon do śledzenia obiektu GDI, w którym dowiedziałem się, że WinLogon ma wysoki wskaźnik wykorzystania, ale to wszystko. Może to być inna usługa, ale zaobserwowano ją na różnych komputerach na różnych usługach korzystających z opublikowanego przeze mnie kodu. To mało prawdopodobne. Myślę, że mam już wystarczająco dużo połączeń GC.Collect(). Więc to też nie pomoże. –

+0

@ TomKos, rozważ użycie wartości 'BitmapCacheOption.None' jako argumentu konstruktora klasy' TiffBitmapDecoder' oraz jako argumentu wywołania metody 'BitmapFrame.Create()'. –

Odpowiedz

2

Operacja zakończona pomyślnie

To tajemnicze wiadomości zawęża dokładny kod w konstruktorze HwndWrapper że zawiedzie. WPF ma błąd w deklaracji pinvoke GetStockObject. Jego właściwość SetLastError = true jest błędna, GetStockObject() w rzeczywistości nie generuje kodu błędu. Widzisz opis kodu błędu 0, "nic nie poszło nie tak".

GetStockObject() jest funkcją winapi, która nigdy nie zawodzi, jeśli otrzyma poprawny argument. Obiekty magazynowe są wstępnie przydzielane i nigdy nie są udostępniane. Masz bardzo mocne dowody na to, że stan procesu jest całkowicie uszkodzony.Widzenie komunikatu "alokacja sterty nie powiodło się" w dzienniku zdarzeń jest z pewnością częścią tej nędzy.

Jeśli nie masz pojęcia, co może spowodować takie uszkodzenie, komputer jest dobrze znany z niezawodną pamięcią RAM, nie używasz niebezpiecznego kodu natywnego, a na komputerze nie są uruchomione żadne inne usługi, które mogłyby uszkodzić stertę komputera, a następnie jedyną dostępną opcją jest utworzenie minizrzutu awarii. Zadzwoń do pomocy technicznej Microsoft, mogą śledzić śledzenie z powodu błędu GetStockObject(). Zważajcie, że musicie przejść przez pierwsze warstwy wsparcia, te, które powiedzą wam, aby zamienić maszynę :)

+0

Dzięki za odpowiedź. Doceniam twoje wyjaśnienie. Mogę spróbować zadzwonić do pomocy technicznej Microsoft, ale nie mam w tym żadnej nadziei. Tymczasem nie rozumiem, jak mogę to rozwiązać. –

Powiązane problemy