Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Portal
  • |
  • Mitglieder
Beiträge von Spook
Thema: ObservableCollection<T> Änderungen aus anderem Thread
Am im Forum: GUI: WPF und XAML

Hallo zusammen,

ich habe ein Problem mit einer ListBox im Zusammenspiel mit einer ObservableCollection<T>.
Grob zusammengefasst passiert folgendes:

Ich habe eine ObservableCollection<T> welcher zuvor einer ListBox (ItemsSource Property) zugewiesen wurde. Zu einem späteren Zeitpunkt wird das Objekt, in welchem die Collection liegt, zerstört. Dabei wird die Collection wieder aus der ListBox entfernt (im GUI Thread).
Danach rufe ich Clear() auf der Collection auf, was zu einer Exception in der ListBox führt, weil der Aufruf aus dem Nicht-GUI Thread kommt.

Hier ein Beispeilcode:

        private void addButton_Click(object sender, RoutedEventArgs e)
        {
            ObservableCollection<string> collection = new ObservableCollection<string>();
            collection.Add("a");
            collection.Add("b");
            collection.Add("c");
            listBox.ItemsSource = collection;
        }

        private void removeButton_Click(object sender, RoutedEventArgs e)
        {
            Thread thread = new Thread(ThreadProc);
            thread.IsBackground = true;
            thread.Start();
        }

        private void ThreadProc()
        {
            ObservableCollection<string> collection = null;

            Action removeItems = () =>
            {
                collection = listBox.ItemsSource as ObservableCollection<string>;
                listBox.ItemsSource = null;
            };

            if (!listBox.Dispatcher.CheckAccess())
            {
                listBox.Dispatcher.Invoke(removeItems);
            }
            else
            {
                removeItems();
            }

            if (collection != null)
            {
                collection.Clear(); // <- Exception
            }
        }

Das Problem ist, dass nach dem Setzten von "listbox.ItemSource = null;" die Listbox immernoch an dem CollectionChanged Event angemeldet ist.
Warum hängt sich die ListBox nicht wieder von dem Event ab? Passiert dies erst zu einem späteren Zeitpunkt?
Wie kann ich sicherstellen, dass alles richtig aufgeräumt ist, bevor ich den GUI Thread wieder verlasse?

Thema: Variablendeklaration im Scope oder außerhalb: Macht das einen Unterschied?
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Hallo Astrix,

Zitat
Wird im Beispiel A in C# bei jedem Schleifenschritt ein Speicherplatz zum Ablegen des Variableninhalts x auf dem Heap belegt und beim Beispiel B nicht (weil x ja wiederverwendet werden würde/könnte)?

Alle in Methoden deklarierten Variablen werden auf dem Stack gespeichert. Dabei sollte es keinen Unterschied machen ob du x innerhalb oder ausserhalb deklarierst. Der Compiler sollte in beiden Fällen die 4 Bytes für die Variable reservieren, d.h. der Speicherplatz muss nicht allokiert oder wieder freigegeben werden.
Zitat
wie C# hier intern arbeitet
Das ist nicht C# spezifisch. Wenn du ähnlichen Code in C/C++/Pascal ect schreibst, sollte am Ende ähnlicher Assembler Code dabei herauskommen.

In Understanding the Stack gibts eine kurze Erlärung, wie der Stack funktioniert.

Grüße

Thema: Deserialisieren eines Enums mit Kombinationen
Am im Forum: Datentechnologien

Hallo gaussmath,

versuche dies zu verwenden:
Flags

Grüße

Thema: Zugriff auf Settings unter .NET 4.5
Am im Forum: GUI: WPF und XAML

Hallo Rainer,

vielleicht wird die Klasse als internal anstatt public vom Designer erzeugt.
Unter 2010 konntest (musstest) du dieses einstellen.

Grüße

Thema: C++- bzw. COM-DLL importieren
Am im Forum: Rund um die Programmierung

Hallo Matthew Gee,

du kannst in .NET nur auf .NET- oder COM-Assemblies verweisen.
Native DLLs musst du (manuell) importieren.

Der Artikel Calling Win32 DLLs in C# with P/Invoke beschreibt die Basics. Ansonsten würde ich nach ".net import native dll" googlen, da sollte es genug Beispiele geben.

Grüße

Thema: Problem mit Byte[] eines Gray8-Images
Am im Forum: Grafik und Sound

Hallo,

solltest du nicht FormatConvertedBitmap verwenden anstatt CroppedBitmap?

Grüße

Thema: Bindung einer statischen Eigenschaft an eine ComboBox
Am im Forum: GUI: WPF und XAML


xmlns:ns="clr-namespace:x.y.z"
...
{Binding Source={x:Static ns:class.property}}

ns = definierter namespace der Klasse

Thema: TextBox: PropertyChanged funktioniert nicht?
Am im Forum: GUI: WPF und XAML

Zitat von punkdevil
Das heißt, nachdem du irgendwas eingegeben hast, steht nach dem LostFocus wieder "MyText" in der TextBox?

Wenn ich den Button anklicke setzt er den Text zurück.
Ich habe DataContext allerdings nach InitializeComponent() gesetzt.

Thema: TextBox: PropertyChanged funktioniert nicht?
Am im Forum: GUI: WPF und XAML

Dein Code, aus dem Startposting, funktioniert bei mir wie erwartet (Update bei Fokusverlust).

Wie weisst du das ViewModel zu?

spooky

Thema: Klassenbibliothek, die externe native DLL benutzt, erstellen und zu einer DLL zusammenfügen
Am im Forum: Entwicklungs- und Laufzeitumgebung (Infrastruktur)

Hallo skullsplitter,

es gibt eine Möglichkeit eine managed und eine unmanaged dll zu mergen.
Der .NET Wrapper von SQLite verwendet diese zum Beispiel.
Das Tool heisst Mergebin. Es bettet eine der beiden in die andere ein.

Hier gibts ein paar Informationen

Hier habe ich den Sourcecode gefunden.

Vielleicht gibts Mergebin auch irgendwo fertig zum runterladen.

Grüße spooky

Thema: [erledigt] Programm beendet durch Application.Exit nicht vollständig
Am im Forum: GUI: Windows-Forms

Hallo NewCannon,

startest du neue Vordergrundthreads?
Diese müssen alle beendet sein, bevor der Prozess beendet wird.

Thread.IsBackground-Eigenschaft

Grüße

Thema: Aufruf ohne Methodennamen - wie ist das möglich? [==> per Pointer]
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Hallo thefiloe,

vielleicht hilft dir dies weiter:
Marshal.GetDelegateForFunctionPointer-Methode

Grüße

Thema: Stack Size erhöhen
Am im Forum: Rund um die Programmierung

Hallo Shera,

ist es möglich für die Berechnung in einem neuen Thread zu machen?
Wenn ja oder dies bereits so ist, kannst du die zu verwendende Stackgröße angeben:
Thread Constructor (ThreadStart, Int32)

Grüße

Thema: Dynamisch geladene Assemblies und Patchen dieser
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Hallo Carryman,

du musst so vorgehen:

  • Neue AppDomain erzeugen
  • In dieser neuen AppDomain die gewünschte Assmbly laden
  • Mit AppDomain.CreateInstanceAndUnwrap einen Proxy erzeugen und verwenden

Damit es bei mir funktioniert hat, musste ich bei der Klasse von MarshalByRefObject erben.

Dann sollte Entladen und Löschen der Assembly bzw AppDomain funktionieren.

grüße spooky

Thema: Dateien (über VPN) von passwortgeschützter Freigabe abholen, ohne ein Laufwerk zu mappen
Am im Forum: Rund um die Programmierung

Hallo Mandy,

über die Kommandozeile kannst du dies mit "net use ..." machen.
Vielleicht kannst du mit deiner Suche da ansetzten.

Grüße

Thema: Bilder aus ImageList wieder freigeben.
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Hallo,

ich verstehe dein Problem so, dass du die Dateien nicht löschen kannst, weil sie durch dein Programm geöffnet sind?!

Wenn ja, dann versuche anstatt Image.FromFile die Methode Image.FromStream zu verwenden, in Kombination mit einem FileStream den du innerhalb eines using-Blockes verwendest. So sollten alle Dateien sofort wieder frei sein.

Grüße

Thema: WPF controls (Image) mittels C-DLL callback updaten
Am im Forum: GUI: WPF und XAML

Wenn die Kanäle so kommen, dann ist es halt so.

Zu deinem Problem:
Das Problem ist relativ simpel:
Die Dispatcher-Klasse regelt die Umleitung in den GUI Thread. Die Klasse Window erbt von DispatcherObject die Property "Dispatcher" vom Typ Dispatcher.

Ich rufe in meinem Code diese Property ab. Da du aber Dispatcher.CurrentDispatcher aufrufst interpretiert der Compiler dies als Aufruf der statischen Property Klasse Dispatcher.

if (!Dispatcher.CheckAccess()) vs
if (!Dispatcher.CurrentDispatcher.CheckAccess())

Und da du den Dispatcher für den momentanen Thread holst ist es logisch, dass auch kein Umleiten nötig ist, es ist ja der selbe Thread ;)

if (!this.Dispatcher.CheckAccess()) ist wohl die bessere, da eindeutigere, Schreibweise in diesem Fall.

Siehe Fzelle: Die Methoden nicht als statisch deklarieren.

grüße

Thema: WPF controls (Image) mittels C-DLL callback updaten
Am im Forum: GUI: WPF und XAML

Hallo greenpepper,

1.

writeableBitmap.Dispatcher.Invoke(new Action<byte[]>(UpdateImageData), pixels);
Den Invoke würde ich weglassen und die Methode direkt aufrufen, denn diese schaut selbst nach ob ein Invoke nötig ist oder nicht (doppelt gemoppelt).

2.
Du schreibst die Farbkanäle getrennt. Es ist auf jeden Fall schneller wenn du ein passendes PixelFormat wählst und den gesammten Puffer mit einem Aufruf von WriteableBitmap.WritePixels kopierst. Falls du nur den AlphaKanal entfernen willst kannst du z.B. Bgr32 nehmen und dieser wird ignoriert.

grüße

Thema: WPF controls (Image) mittels C-DLL callback updaten
Am im Forum: GUI: WPF und XAML

Hallo greenpepper,

ich hoffe, dass dir dies weiterhilft:

        private void YourThreadProc(IntPtr dummyPtr)
        {
            if (!Dispatcher.CheckAccess())
            {
                Dispatcher.Invoke(new Action<IntPtr>(YourThreadProc), dummyPtr);
                return;
            }

            bitmap.Lock();
            byte[] data = new byte[bitmap.Format.BitsPerPixel / 8 * bitmap.PixelWidth];
            Random rand = new Random();
            for (int i = 0; i < bitmap.PixelHeight; i++)
            {
                rand.NextBytes(data);
                IntPtr ptr = bitmap.BackBuffer + (i * bitmap.BackBufferStride);
                Marshal.Copy(data, 0, ptr, data.Length);
            }
            bitmap.AddDirtyRect(new Int32Rect(0, 0, bitmap.PixelWidth, bitmap.PixelHeight));
            bitmap.Unlock();
        }

grüße

Thema: Übergabe von fixed sized array an Funktion
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Hallo hsg,

verwende diese Signatur:

unsafe public void CopyField(string cSource, byte* cDest, int length)

und übergib ebenfalls die Länge des (fixed size) Arrays.
Den Pointer wie ein normales .NET Array indizieren und auf die maximale Länge achten.

Grüße spooky

Thema: Unmanaged dll in c# einbinden und void** als Parameter einer Methode erstellen
Am im Forum: Rund um die Programmierung

Hallo,

definiere void** entweder als "ref IntPtr" wenn der Parameter in/out ist oder als "out IntPtr" wenn er nur out ist.

Als Beispiel:

bool getList(out IntPtr address, ...);
void useList(IntPtr address, ...);

....
IntPtr address = InPtr.Zero;
if (getList(out address, ...))
  useList(address);
...

Grüße

spooky

Thema: Problem mit importiertem C++ DLL: byte*/char* in String / Einfrieren der Anwendung
Am im Forum: Rund um die Programmierung

Hallo Joseph,

[DllImport("pa_dde.dll", CharSet=CharSet.Auto)]
unsafe internal extern static bool Request([MarshalAs(UnmanagedType.LPTStr)] string Variable, [MarshalAs(UnmanagedType.LPTStr)] ref string ReturnStr);

Schau dir den Header der Funktion an und deklariere diese dann mit dem passenden CharSet (anstatt Auto); dann kannst du die MarshalAs-Attribute weglassen.

z.B:

[DllImport("pa_dde.dll", CharSet=CharSet.Unicode)]
internal extern static bool Request(string variable, StringBuilder returnString);

Der Rückgabe-String in Form eines in/out-Parameters ohne weiteren Längen-Parameter ist merkwürdig. Vermutlich gibt es eine vordefinierte Länge (siehe Header/Dokumentation). Benutze anstatt eines 'ref Strings' einen StringBuilder, der mit der benötigten Länge (Capacity) initialisiert wurde und übergib diesen by value.
Nach dem Aufruf kannst du dir den String mit .ToString() geben lassen; schreibe dir eine Wrapper-Funktion.

Deine Abstürze werden vermutlich falsches Marshalling sein, die den Heap oder Stack auf irgend eine Weise corrupten, wenn du zb. einen zu kurzen Buffer übergibst und über den allokierten Speicher hinaus schreibst.

Thema: Problem mit importiertem C++ DLL: byte*/char* in String / Einfrieren der Anwendung
Am im Forum: Rund um die Programmierung

Hallo Joseph,

der Artikel Calling Win32 DLLs in C# with P/Invoke könnte dir als Einstieg dienen. Besonders der Abschnitt über Text Marshalling.

Grüße spooky

Thema: Switch-case-Anweisung mit Strings
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Das beschriebene Problem ist doch, dass er immer in den default block springt und nicht, dass er den switch block optimiert.

Thema: Switch-case-Anweisung mit Strings
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Der Code aus dem Startpost funktioniert ohne Probleme.
Wenn du ToLower() schon versucht hast, warum hast du diese (wohl zum funktionieren essentielle Zeile) wieder gelöscht?

Thema: Switch-case-Anweisung mit Strings
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Hallo Lumbra,

Groß-/Kleinschreibung ggf?

spooky

Thema: [erledigt] VS-Debugger läuft in if, obwohl die Bedingung (angeblich?) nicht erfüllt ist (war?)
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Hallo,

ich verwende zum Beispiel Code Contracts. Die kompilierten Assemblies werden dabei umgeschrieben was dazu führt, dass die angezeigten Zeilen mit den tatsächlichen manchmal nicht übereinstimmen.
Vielleicht ist es in deinem Fall ähnlich?

spooky

Thema: [erledigt] Prüfen ob Property einen TypeConverter hat
Am im Forum: Basistechnologien und allgemeine .NET-Klassen

Hallo Alex,

dies sollte dir weiterhelfen:

MemberInfo.GetCustomAttributes()

Grüße

Thema: [ungelöst] Anwendung startet mal, mal nicht
Am im Forum: Rund um die Programmierung

Hallo DNAofDeath,

ist die "SQLite.Interop.dll" ebenfalls vorhanden? Hast du die Exception bis auf die Root-Exception (.InnerException Property rekursiv) durchsucht? Was sagt diese?

spooky

Thema: Zwei Objekten zu einer XML
Am im Forum: Datentechnologien

Hallo HerrOli,

die Klasse "Person" muss public sein.

spooky