| 

.NET C# Java Javascript Exception

1
Hallo,

ich bin neu hier und dazu noch Anfänger in C#.

Die folgende Methode soll in meinem Programm arbeiten:
internal bool Compress(byte[] input, ref byte[] output)
{
try
{
using (MemoryStream ms = new MemoryStream())
{
using(GZipStream gzs = new GZipStream(ms, CompressionMode.Compress))
{
gzs.Write(input, 0, input.Length);
gzs.Flush();

output = ms.ToArray();

}
ms.Flush();
return true;
}
}
catch {return false;}
}


Mindestens bis 2 GB soll diese durchgeführt werden können (läuft fehlerfrei). Die Geschwindigkeit ist rel. langsam, deshalb möchte ich eine Abbruchmöglichkeit einbauen. Vielleicht hat auch jemand eine Idee, wie ich die Methode beschleunigen könnte? Hauptsächlich möchte ich aber eine sichere Abbruchmöglichkeit.

Google hat mich eher verwirrt als mir nachvollziehbare Lösungsansätze zu zeigen.

Ich freue mich auf jede hilfreiche Antwort.

boga
News:
05.09.2013
boga 71 5
1 Antwort
1
Zur späten Stunde nur eine kurze Skizze: gib der Methode einen Parameter mit, über den der Aufrufer einen Abbruch signalisieren kann (z.B. ein CancellationToken, wenn Du mit Tasks arbeitest). In Deiner Methode schreibst Du nicht den kompletten input auf einmal in den GZipStream, sondern (in einer Schleife) immer nur einen Block (z.B. 1MB). Zwischendurch prüfst Du den Zustand des Tokens und brichst die Schleife ggf. ab.
06.09.2013
Matthias Hlawatsch 13,2k 4 9
Wenn ich, so betrachtet, auf diese Art Blöcke verarbeite, wird in jedem Block (vermutlich) viel zus. Info-Müll über Icon, etc. enthalten sein, was def. nicht erwünscht ist. Aber schon mal vielen Dank für andere Wege.
boga 06.09.2013
das mit "Info-Müll" und "Icon" verstehe ich ehrlich gesagt nicht...
Matthias Hlawatsch 06.09.2013
Bei jedem erneuten GZip-Durchlauf werden, meiner Meinung nach, zus. Platzhalter mit durchgeschleppt, die nicht benötigt werden und bei einer beispielsweise angehängten Verschlüsselung Muster bilden könnten. Oder habe ich da etwas nicht verstanden?
boga 06.09.2013
Also ich hatte das in etwa so gemeint, dass Du die Zeile

gzs.Write(input, 0, input.Length);

ersetzen sollst durch etwas wie

for (int i = 0; i < input.Length; i += 1024*1024)
{
if (abbruchbedingung) return false;

gzs.Write(input, i, 1024*1024);
}

Ich habe nur wenig Erfahrung mit GZipStream, aber ich würde erwarten, dass das Ergebnis identisch wäre mit Deinem Ansatz. Probiere es vielleicht einfach mal aus.
Matthias Hlawatsch 06.09.2013
Mit dem Replace werde ich mal etwas testen, danke. Den Abbruch habe ich inzwischen über Task hinbekommen. Meine Test-Lösung zeige ich, aus Platzgründen, im folgenden Kommentar. Ich benötige jetzt keine weitere Hilfe mehr, es sei denn, mein Lösungsansatz ist zu verbessern.

boga 06.09.2013
bool y = false;

internal void Button1Click(object sender, EventArgs e)
{
cts = new CancellationTokenSource();
token = cts.Token;

Task myTask = Task.Factory.StartNew(() =>
{
while (!y)
{
token.ThrowIfCancellationRequested();

y = funk();
if(y == true)
MessageBox.Show("Fertig");

}
}, token);
}

internal void Button2Click(object sender, EventArgs e)
{
cts.Cancel();
if (token.IsCancellationRequested)
MessageBox.Show("Abbruch");
}
boga 06.09.2013

Stelle deine .net-Frage jetzt!
TOP TECHNOLOGIES CONSULTING GmbH