Hi,
Gibt es die Möglichkeiten eine laufende Deserialisierung mit BinaryFormater in C# zu canceln (z.B. wenn User auf Escape Taste drückt)?
Wurde bei meiner Suche leider weder in der Doku noch mit Google fündig.
Würde mich freuen falls mir da jemand weiterhelfen bzw. in die richtige Richtung leiten könnte.
Grüße,
Timo
Hallo cyc,
herzlich willkommen hier auf myCSharp.de!
Gibt es die Möglichkeiten eine laufende Deserialisierung mit BinaryFormater in C# zu canceln (z.B. wenn User auf Escape Taste drückt)?
Nein - die gibt es nicht.
So eine Möglichkeit würde aber auch nicht wirklich viel Sinn machen, da der BinaryFormatter sowieso nur für "kleinere" Datenmengen konzipiert ist. Diese sollte er dann in weniger als einer Sekunde abarbeiten können.
Evtl. blockiert etwas anderes bei dir so lange?
Oder deine Datenmengen sind einfach zu groß - in diesem Falle solltest du erwägen, auf eine Datenbank auszuweichen. Diese sollten da um einiges performanter zu Werke gehen.
Was serialisierst bzw. deserialisierst du denn?
Evtl. lassen sich ja auch manche Daten weglassen.
Die Daten sind binär serialisiert maximal ca. 40 mb (Messdaten) groß und schon soweit reduziert, dass sie nur das nötigste enthalten.
Leider ist die Vorgabe, dass dass Programm ist keine Datenbank verwendet soll.
Bisher war ich mit der binären Serialisierung recht zufrieden (z.B. über eine Wrapperklasse war es mir möglich eine ProgressBar upzudaten und Geschwindigkeitsprobleme konnte ich durch geignetes Datenlayout in den Griff bekommen).
Ich denke ich habe jetzt eine Lösung gefunden:
Die Idee ist hier folgende und baut auf die ReadProgressStream und ContainerStream Klasse aus folgendem Artikel auf:
.NET Matters: Deserialization Progress, and More
zusätzlich definiere ich eine Exception falls von Aussen die Deserialisierung Unterbrochen wurde:
public class DeserializationException : System.ApplicationException
{
public DeserializationException() { }
public DeserializationException(string message) { }
public DeserializationException(string message, System.Exception inner) { }
// Constructor needed for serialization
// when exception propagates from a remoting server to the client.
protected DeserializationException(System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context) { }
}
Zusätzlich nehme ich folgende Änderungen vor:
public bool canceled = false; // neu !!!!!!!!
public override int Read(byte[] buffer, int offset, int count)
{
if (canceled) throw new DeserializationException(); // neu !!!!!!!!
int amountRead = base.Read(buffer, offset, count);
if (ProgressChanged != null)
{
int newProgress = (int)(Position * 100.0 / Length);
if (newProgress > _lastProgress)
{
_lastProgress = newProgress;
ProgressChanged(this,
new ProgressChangedEventArgs(_lastProgress, null));
}
}
return amountRead;
}
Hiermit ist die Deserialisierung von Aussen (ProgressChangedEvent handler) abbrechbar.
Hoffe damit jemand helfen zu können falls er auf das selbe Problem stösst.
Grüße,
Timo
Hallo,
Die Daten sind binär serialisiert maximal ca. 40 mb (Messdaten) groß und schon soweit reduziert, dass sie nur das nötigste enthalten.
Leider ist die Vorgabe, dass dass Programm ist keine Datenbank verwendet soll.
Serialisierung ist schon eine nette sache aber 40MB sind IMHO ein bisschen zu viel des Guten.
Es gäbe auch die lokalen Datenbanken die ohne Installation und Server funktionieren.
z.B. SQL Compact, Firebird...
Vielleicht kannst du sowas ja verwenden denn damit könntest du um einiges konfortabler arbeiten weil du nur die Daten laden musst die du auch brauchst.
Gruss
Michael
Hallo cyc,
man sollte Exceptions nicht verwenden um den Programmfluss zu steuern.
Abgesehen davon, sollte man keine öffentlichen Felder machen. Verletzt die Kapselung der OO.
Ja geb ich zu ist eher ein Hack.
Dient eher dazu zu zeigen, dass es grundsätzlich möglich ist.
Habt ihr einen Vorschlag wie ich ohne Exception in diesem Fall auskomme?
Grüße
Timo
Hallo cyc,
noch einfacher wäre es mit LINQ to XML. Dort hast du auch dir Möglichkeit zum Streamen. Und Parallelisieren ist auch möglich. Serialisierung würde ich persönlich nicht verwenden.
zero_x
zero_x | <span style="font-size: 10;">my</span><span style="font-size: 10;">CSharp</span><span style="font-size: 10;">.de</span> - gemeinsam mehr erreichen
Für längere Zeit inaktiv.
Hallo Stefan O.,
man sollte Exceptions nicht verwenden um den Programmfluss zu steuern.
Immer dieses dogmatische Denken. Ich steuere IMMER den Programmfluss, sobald ich eine Exception werfe. Darf ich jetzt nach Deiner Aussage folgend niemals eine Exception werfen?
Den aktiven Abbruch eines lang laufenden Prozesses durch den Benutzer halte ich für einen absolut legitimen Grund, eine Exception zu benutzen. Das ist aus meiner Sicht auch kein Hack.
MfG,
N1ls
Natürlich werden mit Exceptions auch der Programmfluss gesteuert, aber nur wenn es nicht anderst geht, wenn eben eine Exception auftritt, die man nicht vorhersehen konnte.
Zum Beispiel bevorzuge ich:
if (File.Exists(myFile))
{
using (FileStream stream = new FileStream(myFile, FileMode.Open))
{
...
}
}
else
{
// Error Handling, Whatever
}
anstatt
try
{
using (FileStream stream = new FileStream(myFile, FileMode.Open))
{
...
}
}
catch (FileNotFoundException)
{
// Error Handling, Whatever
}
Ich würde in deinem Fall auf jeden Fall ein Event Cancelled oder so erstellen.
ImageTools for Silverlight: http://imagetools.codeplex.com | http://www.silverdiagram.net | http://www.cleancodedeveloper.de b:::
ABer beim Serialisieren geht da nix, weil man kein Fuß dazwischen kriegt.
cyc hat da schon eine schlaue Lösung mit einem speziellem Stream, aber wenn man dessen Lesevorgang mw. sauber vorzeitig beendet, schmeißt eben der BinaryFormatter eine Exception, weil er das Objekt nicht bilden kann.
Der frühe Apfel fängt den Wurm.
man sollte Exceptions nicht verwenden um den Programmfluss zu steuern.
Zum Abbrechen eines Vorganges halte ich die Verwendung von Exceptiosn schon legitim - macht ja auch CancellationToken.
Hallo!
Wie wäre es mit der Auslagerung in einen eigenen Thread? Somit ist zum einen die UI nicht blockiert, und mit Thread.Abort ist ein Abbruch möglich.
Nobody is perfect. I'm sad, i'm not nobody 🙁
@malignate :
Files und andere Öffentlich zugängliche Objekte sind ein sehr schlechtes Beispiel für diese Herangehensweise.
Wenn zwischen deinem File.Exists und dem Zugriff die Datei "verschwindet" hast du ein Problem.
Also bei Files, kannst du gleich auf die Exception gehen, ansonsten ist es aber sicherlich richtiger erst abzufragen, als ins Messer zu laufen.
@N1ls:
Nur wenn man verstanden hat, was man wo, warum macht/nicht macht, kann man von Pragmatismen abweichen, aber sie von Vornherein zu verneinen zeigt auch ein gewisses Unverständnis.
Hallo,
Serialisierung ist schon eine nette sache aber 40MB sind IMHO ein bisschen zu viel des Guten.
Warum?
@FZELLE: Vielen Dank für den Hinweis, obwohl es so offensichtlich ist, habe ich bisher nie daran gedacht.
Fühle mich gerade richtig blöd.
ImageTools for Silverlight: http://imagetools.codeplex.com | http://www.silverdiagram.net | http://www.cleancodedeveloper.de b:::