Laden...
B
Borg myCSharp.de - Member
Berlin, Germany Dabei seit 23.08.2006 1.529 Beiträge
Benutzerbeschreibung

Forenbeiträge von Borg Ingesamt 1.529 Beiträge

12.03.2007 - 11:45 Uhr

Ja.

11.03.2007 - 23:44 Uhr

Du solltest aber nicht ein par hundert Bilder als Base64 kodieren und in XML speichern. Speichere lieber die Bilder als Dateien in ein Zip und füge eine XML-Datei hinzu, die die Dateinamen der Bilder mit den zusätzlichen Informationen verknüpft.
Ansonsten gibt es ja auch noch EXIF und IPTC...

11.03.2007 - 16:07 Uhr

Zitat MSDN-Lib:

Calling Set signals AutoResetEvent to release a waiting thread. AutoResetEvent remains signaled until a single waiting thread is released, and then automatically returns to the non-signaled state. If no threads are waiting, the state remains signaled indefinitely.

Das bedeutet also, dass nur ein einziger Thread das WaitOne abschließt, alle anderen warten weiter.

11.03.2007 - 15:43 Uhr

Ich verstehe nicht ganz, was die Anzahl der Threads mit der Funktionalität des AutoResetEvents zu tun haben soll?

11.03.2007 - 15:18 Uhr

Das sagte ich doch. Dein Computer muss mathematische Strukturen erfassen, d.h. parsen können.
Hast du einen solchen Parser, könntest du beispielsweise schreiben:

# die Raute ist Kommentar; mit => sind die Antworten des Systems gekennzeichnet
# Weg
DEFINE ENTITY s CALL "Weg"
DEFINE UNIT "m" AS s CALL "Meter"
DEFINE UNIT "km" AS s WHERE [km]=[m]/1000 CALL "Kilometer"
# Zeit
DEFINE ENTITY t CALL "Zeit"
DEFINE UNIT "s" AS t CALL "Sekunde"
DEFINE UNIT "min" AS t WHERE [min]=[s]/60 CALL "Minute"
DEFINE RELATION s(t) CALL "Weg nach Zeit"
# Geschwindigkeit
DEFINE ENTITY v CALL "Geschwindigkeit"
DEFINE RELATION v(t)=s'(t) CALL "Geschwindigkeit nach Zeit"
# Beschleunigung 
DEFINE ENTITY a CALL "Beschleunigung"
DEFINE RELATION a(t)=v'(t) CALL "Beschleunigung nach Zeit"

# beschl. Bewegung: s = a/2*t²
SET meinSturz AS s(t)=9.81/2*t*t
=> meinSturz:s(t)=9.81/2*t*t

CALC meinSturz(5) 
=> 122.625 m
CALC meinSturz(5) IN "km"
=> 0.122625 km

SET meineGeschw AS v(t) FROM meinSturz
=> meineGeschw:v(t)= meinSturz:s'(t) = 9.81*t
CALC meineGeschw(10)
=> 98.1 m/s

SET meineBeschl AS a(t) FROM meinSturz
=> meineBeschl:a(t) = meinSturz:v'(t) = meinSturz:s''(t) = 9.81
CALC meineBeschl(17)
=> 9.81 m/s²
CALS meineBeschl(17) IN "s:km;t:min"
=> 35,316 km/min²

Das Beispiel ist jetzt zwar etwas umfangreicher geworden, aber ich hoffe, es macht deutlich, wie ich das meinte. Du benötigst also zuerst mal eine Syntax, dann einen Parser dafür. Dieser generiert ein Netz mit Beziehungen zwischen verschiedenen Entitäten. Parameter dieser Beziehungen sind die Operationen, welche du natürlich auch kennen musst.
Das bedeutet, in deinem Code gibt es gar keine Klassen, die den verschiedenen physikalischen Größen entsprechen, sondern nur eine Entitäten-Klasse und eine Beziehung-Klasse. Die Logik kommt durch die Verknüpfungen von Entitäten und Beziehungen zustande.

EDIT*: Beispiel überarbeitet.

11.03.2007 - 14:46 Uhr

Oder kurz (dafür ohne weitere Einflussnahme):

Process.Start( "myapp.exe", "myarguments" )

Davon gibt es auch eine weitere Überladung, bei der du Benutzername und Passwort angeben kannst, mit dem der Prozess gestartet werden soll.

11.03.2007 - 14:28 Uhr
  1. Sorry, wenn ich dass sage, aber wenn du Ampère nicht richtig schreiben kannst und von Grad Kelvin redest, sehe ich von physikalischer Seite schwarz.

  2. Um das ganze auf ein halbwegs sinnvolle Grundlage zu stellen, würde ich nicht die Einheiten sondern die physikalischen Größen per Klasse erfassen.
    Also hättest du dann Klassen wie Weg, Masse, Zeit, elektrische Stromstärke, Temperatur, Stoffmenge und Lichtstärke, die intern ausschließlich die SI Grundeinheiten verwenden.
    Die Klasse würde dann Methoden zur Umrechnung anbieten. Wenn du also eine Instanz von Temperatur mit dem Wert 1000 (laut SI also 1000 Kelvin) hast, bietet diese ein Methode namens InCelsius an, welche in diesem Fall 726.85 liefern würde.

  3. Dennoch, wird dies allein nicht sehr sinnvoll werden, wenn du dem Computer die Unterscheidung zwischen Einheiten nahe bringen willst. Das eigentliche Problem stellt ja nicht die Klassenstruktur dar (auch wenn ich nicht glaube, dass es sinnvoll ist, dafür eine Struktur zu erstellen). Das Problem ist vielmehr, dass du dem Computer die sinnvollen Verknüpfungen zwischen beispielsweise Weg s und Zeit t darlegen musst. Davon gibt es aber mehrere (Länge s, Fläche s², Volumen s³, Geschwindigkeit s/t, Beschleunigung s/t²). Daher macht es in meinen Augen nur Sinn, dass auf die mathematische Grundlage zu stellen. Also Geschwindigkeit v = ds/dt u.ä. Um also physikalische Beziehungen sinnvoll darstellen zu können, müsstest du erstmal mathematische Beziehungen erfassen und darstellen können. Schließlich stellen die physikalischen eine Untermenge der mathematischen dar.

  4. Wenn es dir nur um Umrechnung zwischen den Einheiten geht, benötigst du diese ganzen Strukturen nicht, das ist relativ problemlos möglich.

11.03.2007 - 14:04 Uhr

Auch zum letzten Mal:
Wir haben dich verstanden. Wir haben dir auch gesagt, wie du verschiedene Rechner anpingen kannst.

Allerdings verwendet Ping ein ICMP Echo Request (Internet Control Message Protocol), welches auf IP (Internet Protocol) basiert. Daher kann man auch keine bestimmten Ports anpingen, da es Ports erst im ebenfalls IP-basierten TCP (Transmission Control Protocol) gibt, sondern nur bestimmte IP-Adressen.
Um jetzt die Ports zu scannen, müsstest du dich im einfachsten Fall jeweils per UDP und TCP mit ihnen zu verbinden versuchen. Was auch immer du tust, so wirst du doch nur feststellen, dass du keine Lücke hast, die jemand, der genauso viel wie du weiß, finden würde...
Um mit (relativer) Sicherheit irgendwelche Aussagen treffen zu können, müsstest du jedoch einen ganzen Stapel von Tests über die Ports laufen lassen.
Da dir diese Kenntnisse fehlen, wiederhole ich noch einmal, dass du keinen wirklichen Erfolg haben wirst.

Lad dir lieber einen der vielen Portscanner runter. Wenn du dich doch etwas mehr in die Thematik vertieft hast, kannst du auch nmap verwenden (gibt es auch für Windows: nMapWin).

11.03.2007 - 13:38 Uhr

Ich frage mich jetzt ehrlich gesagt, was die Speicherung von "mehreren TB" Videos mit deinen obigen Fragen (vor allem der ersten) zu tun hat???

Aber um es kurz zu sagen: Videos kannst du nicht mit einer der allgemeinen Packer (ZIP, RAR etc.) weiter komprimieren. Dabei kommen höchstens 1% bis 3% Verkleinerung heraus, dafür muss die Datei aber ewig gepackt und entpackt werden (wieder Latenz/Durchsatz in Relation zum Speicher).
Die einzige Möglichkeit Videos zu verkleinern ist deren Bitrate zu reduzieren. Um den damit einhergehenden Qualitätsverlust so gering wie möglich zu halten, sollte man dazu aber formatspezifische Requantisierer einsetzen...

Ausserdem bekommst du momentan interne 500GB Festplatten für locker 120€.
Besorg dir nen alten Rechner (400MHz reichen locker, ideal wäre ein älterer Server mit PCI-X) mit LAN (Gigabit, wenn Netz-Infrastruktur und PCI-X vorhanden) und zusätzlichen IDE-Controllern, knall dort Linux rauf und immer wenn du Bedarf hast, baust du eine neue Platte ein..

11.03.2007 - 13:23 Uhr

Wenn du eine eindeutige Beziehung Parametername <=> Parametertyp hast, sind jeweils eigene Methoden empfehlenswert.
Nur falls deine Klasse allgemein auf unbekannte Typen mit unbekannten Namen losgelassen würde (beispielsweise zur Abfrage von INI-Dateien), würde ich

public static T GetValue<T>( string ValueName )

verwenden.

09.03.2007 - 17:31 Uhr

Dann musst du versuchen, dich mit der Systemdatenbank des DBMS zu verbinden.
Scheitert das, gibt es kein DBMS (bzw. keine Verbindung). Dort kannst du dann die Systemtabelle abfragen, in der alle vorhandenen Datenbanken aufgelistet sind.

09.03.2007 - 14:08 Uhr

Der Preis um dieserart 1/8 des Speichers zu sparen beträgt mindesten eine Verzehnfachung der Latenzzeit und eine deutliche Verringerung des Durchsatz.
Das ist kontraproduktiv, da Rechenzeit teurer als Speicherplatz ist.
Speicher einfach ein Byte (eventuell in einen eigenen Datentyp mit Wertebereichsprüfung verpackt) und gut ist.

09.03.2007 - 14:01 Uhr

Generell: Syntaxfehler selbst lösen (Compilerfehlermeldungen)

Speziell:
Im Designer für .NET 2.0 werden zwei Dateien pro Form erzeugt. Eine mit generiertem Code, die andere mit dem benutzerspezifizierten.
Ermöglicht wird dies durch das neue 2.0er Feature der partial class, wodurch sich eine Klassendefinition über mehrere Dateien verteilen lässt.
Um dies zu nutzen, muss der partial-Modifizierer in jeder Datei vor der betreffenden Klasse aufgeführt werden.
Vermutlich hast du den vom Designer erzeugten Code verändert und den Modifizierer dabei entfernt. Füge ihn einfach zwischen public und class wieder ein.

09.03.2007 - 11:05 Uhr

Nicht per Default, da Windows die Threads eines Prozesses (korrekterweise) zusammenhält.
Deswegen bringt MultiCore (oder SMP) auch nur etwas, wenn die Anwendung mitspielt.
Siehe Thread auf einem bestimmten Core/Kern laufen lassen

09.03.2007 - 10:53 Uhr

Das Problem bei dieser Klasse ist, dass sie nicht zum Arbeiten auf einem FTP-Server gedacht ist, sondern nur zum schnellen Hoch- und Runterladen von Dateien.
Wenn du mehr Komfort möchtest, musst du das FTP selbst implementieren.

oder dich nach einer alternativen Klasse umschauen.

09.03.2007 - 10:49 Uhr

Schon mal probiert den angegebenen XML-Schnipsel in eine Datei mit dem gleichen Namen wie dein Executable und einem ".manifest" angehangen ins gleiche Verzeichnis zu packen?
Genau das steht dort nämlich, unabhängig von VB oder C#.

09.03.2007 - 10:38 Uhr

Nutze statt eines Casts den AS-Operator. Dieser generiert keine Exception bei einem unerlaubten Casts, sondern liefert NULL.

private void FocusText(object sender, EventArgs e)
{
   TextBox textBox = sender as TextBox;
   if (textBox == null)
      return;
   textBox.SelectAll();
}
08.03.2007 - 23:26 Uhr

GIER!!!

Wieso morgen erst? Heute war gestern auch morgen und ist genauso gut wie das Morgen von heute...

08.03.2007 - 23:18 Uhr

Ich weiß nicht genau, was du mit Ereignis meinst. Falls du auf eines der Events der Klassen in System.Forms anspielst: ein Dienst hat kein UI und daher greifen auch die Klassen nicht.

08.03.2007 - 23:14 Uhr

Benutze bmp.Width und bmp.Height anstelle der Konstanten 16 sowie Spalte und Zeile oder x und y anstelle von i und j und diese und ähnliche Fehler werden ausgeschlossen oder erschwert...

PS.: Man nenne mir einen Satz mit fünf "und"!
Malt der Malergeselle ein Schild für den Obst und Gemüse Laden und zeigt es zur Abnahme dem Meister. Dessen Kommentar: "Schon nicht übel, aber zwischen Obst und und und und und Gemüse musst du noch mehr Platz lassen!"

08.03.2007 - 12:28 Uhr

Das geht relativ problemlos.
Nur ist es nicht nötig, da du per WMI auch andere Rechner abfragen kannst (solange du die passenden Rechte hast, wovon ich in einem AD eigentlich ausgehe).

08.03.2007 - 11:08 Uhr

eine weitere altenatieve wäre wenn du mit dem router kommunizieren könntest

Wenn es aktiviert ist => UPnP
Ansonsten => Verbindungsversuch wie blackcoin sagte

07.03.2007 - 16:30 Uhr

Trenne Kapitel von Unterkapitel.
Bei der Eingabe einfach am Punkt aufteilen und in zwei verschiedene Spalten. Dann kannst du numerisch nach den Spalten sortieren.

07.03.2007 - 16:28 Uhr

Von 2000 als Obergrenze war auch nie die Rede. Im Protected-Mode des x86-Designes hat das TaskSelector-Register eine Breite von 32Bit. Damit könnte es theoretisch rund 4 Milliarden hardware-gestützte Tasks geben.
Wenn man das ganze per Software macht (wie Win32), ist man prinzipiell in der Anzahl der Tasks unbeschränkt.

Die einzige effektive Einschränkung, die auch auf der oben verlinkten Seite angegeben ist, stellt damit der Speicherplatz dar (jeder Thread bekommt ja einen eigenen Stack). Ein 32Bit Programm nutzt unter Windows per Default 2GB virtuellen Adressraum, möglich sind auch 3GB. Da der Speicherplatz von Windows in 64KB-Blöcken vergeben wird, ergibt sich ein theoretisches Maximum für das Win32-System von 2GB / 64KB (bzw. 3GB / 64KB) und damit 32.768 (bzw. 49.152) Threads.

Allerdings läuft bei einer Anwendung, die mehr als hundert Threads pro Prozessor unterhält, mit Sicherheit etwas schief.
Ein paar Dutzend sind aber kein Problem. Solange sichergestellt ist, dass die Anwendung nicht immer neue Threads aufmacht... Aber dazu gibt es ja den ThreadPool.

07.03.2007 - 15:41 Uhr

http://blogs.msdn.com/oldnewthing/archive/2005/07/29/444912.aspx

Ein Event wird nicht verpennt. Das nächste Mal, wenn der Thread aktiviert wird, wird das Event ausgelöst.

EDIT:

ein knappes Duzend Threads

schalte mal im Taskmanager die Spalten Handles und Threads sichtbar und starte ein Programm, dass auch nur unwesentlich umfangreicher als MineSweeper ist...

07.03.2007 - 15:20 Uhr

Crossposts sind hier nicht gerne gesehen.

EDIT: Da dies jedoch das richtige Forum ist: zum Bearbeiten der Dienstkonfiguration benötigst du Administratorrechte.

07.03.2007 - 11:57 Uhr

Was ist mit

FileStream myFile = new FileStream( "FileName", FileMode.Open, FileSystemRights.ReadData, FileShare.ReadWrite, x * 4096, FileOptions.None);
07.03.2007 - 11:33 Uhr

Es ist auch möglich, dass benötigte andere Dienste (wie z.Bsp. das Ereignisprotokoll oder der RPC-Server) noch nicht gestartet wurden. Du müsstest dann in deinem Dienst angeben, dass er von diesen Diensten abhängig ist, damit er erst danach gestartet wird (ServiceInstaller.ServicesDependedOn).

07.03.2007 - 11:27 Uhr

Öffnest du sie mit FileMode.Open, FileAccess.Read und FileShare.ReadWrite?

07.03.2007 - 11:15 Uhr

Zum Thema Ping:
Du benötigst keine eigenen Threads, sondern kannst einfach _
System.Net.NetworkInformation.Ping.SendAsync()_ verwenden.

Zum Thema PortScan:
Um das zu bewerkstelligen, benötigst zu allererst mal Netzwerkkenntnisse, die du nicht hast.

07.03.2007 - 10:53 Uhr

Zitat MSDN-Lib zu FtpWebRequest.Method:

You can set Method to any command recognized by the server and use the FtpWebRequest object to send the command. This works as expected only if the command does not require you to send data and the server does not send data in response to the request.

Das Problem bei dieser Klasse ist, dass sie nicht zum Arbeiten auf einem FTP-Server gedacht ist, sondern nur zum schnellen Hoch- und Runterladen von Dateien.
Wenn du mehr Komfort möchtest, musst du das FTP selbst implementieren.

06.03.2007 - 23:34 Uhr

Innerhalb der x86-FPU werden alle Zahlen in einem Format mit 80 Bit gespeichert (Extended unter Turbo Pascal). Ausschließlich beim Laden oder Speichern von Werten werden diese in das angegebene Format (Single oder Double) gewandelt.
Intern wird in der FPU immer in diesem Format gerechnet. Daher können nur erste langwierige Operationen unterschiedlich lange dauern, da bei Wandlung von Single nach Extended mehr Bits null sind (und evtl. nicht berechnet werden müssten), als bei Wandlung von Double nach Extended. Nach dieser Berechnung enthält das interne FPU-Register die gleiche Bitfolge (abgesehen von Rundungsfehlern) und alle folgenden Berechnungen dauern wieder gleich lang.

Insofern ist es blödsinnig zu behaupten, dass eines der beiden Formate schneller ist als das andere. Der einzige Grund, warum zur Visualisierung Single verwendet wird, liegt wirklich in der ausreichenden Genauigkeit und in den SIMD-Fähigkeiten moderner C-/G-PUs.

Wer sich darüber genauer informieren möchte, soll sich bitte folgende Wikipedia-Artikel durchlesen:
Gleitkommazahl
IEEE 754

06.03.2007 - 23:12 Uhr

Ich habe die Klasse zwar noch nie zum Umbenennen benutzt, aber ich vermute mal, du musst einen neuen Request mit dem alten Dateinamen erzeugen, die Methode auf Rename setzen, das Property RenameTo auf den neuen Namen setzen und dann per GetResponse ausführen...

06.03.2007 - 23:01 Uhr

Hallo Borg,

wie meinst du basiert? byte ist sealed.

herbivore

Mit auf "Byte basiert" meinte ich natürlich nicht Vererbung sondern Aggregation in einen eigenen Datentyp, der dann auch eigene Operatoren und implizite und explizite Konvertierungen definiert.

06.03.2007 - 22:52 Uhr

Wenn du Sicherheit willst:

Zuerst mit System.Security.Cryptography.SHA512Managed.ComputeHash das Passwort hashen, dann mittels System.Security.Cryptographie.ProtectedData.Protect den Hash verschlüsseln und anschließend per IsolatedStorage speichern.

06.03.2007 - 12:52 Uhr

Du könntest aber einen Typen schaffen, der auf Byte basiert und die Einhaltung des Wertebereichs prüft.

06.03.2007 - 12:36 Uhr

@Armitage: Das ist doch wohl ein Witz. Den Post hättest du dir wirklich sparen können.

Stimme meinen Vorrednern soweit zu, daher hier nur Add-Ons:
1. Das es wie ein englisches Buch geschrieben ist. Ich finde den Schreibstil vieler deutscher Autoren knochentrocken. Es klingt immer so, als wenn sie gerade eine Enzyklopädie schreiben würden. Das macht ein Buch, das man durchlesen und -arbeiten soll sehr mühsam.
2. Wie meine Vorredner, allerdings möchte ich deutlicher auf den Code zu sprechen kommen. Ich finde es sehr wichtig, dass der Code wie aus einem Guss wirkt. Und da die Programmiersprache unabänderbar englisch ist, sollte sich der eigene Code auch daran orientieren (sprich: alles englisch).
3. Habe zwar noch nie ein Add-In für VS programmiert, aber wie dr4g0n76 ansprach, kann es viele Probleme geben. Um schnell die Lösung zu einem konkreten Problem zu finden, ist eventuell ein eigenes Kapitel als schnelle Referenz derartiger Probleme empfehlenswert.

06.03.2007 - 12:12 Uhr

Der Grund liegt aber eher darin, dass Single mit 23Bit Genauigkeit für die Visualisierung ausreichend genau ist (Positionierung auf ca. ein Achtmillionstel möglich).
Desweiteren kann man per SIMD (SSE, 3Dnow, Altivec) gleich vier Single-Werte auf einmal verarbeiten, d.h. einen ganzen Vektor pro Befehl, was 3D-Grafik erst möglich macht. Die GPU setzt daher auch auf single.

Nur für wissenschaftliche Berechnung (bzw. Berechnungen, die nicht ausschließlich der Visualisierung dienen) nutzt man ein Format mit höherer Genauigkeit (52Bit), also Double.

Und ausschließlich für kaufmännische Berechnungen, die ja immer im Dezimalsystem stattfinden, benutzt man Decimal (Orientierung an COBOL). Dieses wird per Software im BCD-Format berechnet und kennt daher nicht das Problem, dass es (Dezimal-)Zahlen gibt, die nicht ohne Verlust in eine binäre Darstellung umgewandelt werden können. Rundungsfehler gibt es beim Rechnen in diesem Format trotzdem, nur keine Umwandlungsfehler mehr.

06.03.2007 - 11:56 Uhr

Sie sind ja auch überladen. Sie tragen den gleichen Namen, haben aber eine unterschiedliche ParameterLISTE. Wohlgemerkt P.-Liste, nicht Parameter.

05.03.2007 - 11:10 Uhr

Die Dateiinfos werden in benutzerdefinierten Attributen des MFT-Eintrags der Datei gespeichert. Damit ist das ganze eine NTFS-Spezialität und daher nicht im Framework reflektiert.
Zur Nutzung musst du daher wohl aufs WinAPI ausweichen (bzw. wahrscheinlich gibt es ein COM dafür).

03.03.2007 - 17:40 Uhr

Alle WMVs, die ich auf die Schnelle auf der Platte gefunden habe, fangen mit den folgenden 16 Bytes an: 30 26 B2 75 8E 66 CF 11 A6 D9 00 AA 00 62 CE 6C...

02.03.2007 - 14:05 Uhr

Das einfachste ist es, wenn du den String vorher verlängerst.

string input = textBox1.Text;
if ((input.Length % 16) != 0)
{
   input += new string( ' ', 16 - (input.Length % 16) );
}
// weiter wie bisher
02.03.2007 - 13:56 Uhr

In diesem einfachen Fall reicht es aber, wenn jeder Befehl eine eigene Zeile bekommt. Du sendest also nach jedem Befehl ein "\n".
Der Server trennt die Daten an jedem "\n" und gibt jede vollständige Zeile zur Verarbeitung weiter.

PS.: In diesem Fall solltest du wirklich NICHT Environment.NewLine verwenden, da die Anwendungen ja - zumindest theoretisch - auf verschiedenen OS laufen können...

02.03.2007 - 13:15 Uhr

Dauert wirklich ewig. Das Problem ist, dass der jedes Mal alles neu überträgt. Da dauert vor allem der riesige Baum links ewig lange. Und bis das dann alles fertig gerendert ist.
Das sollte MS eigentlich besser können. Das wäre doch mal eine Werbung für ihr Atlas...

02.03.2007 - 13:05 Uhr

Aktiviere mal den zugrunde liegenden ToolStrip per this.ActiveControl. Dieser ist nämlich von Control abgeleitet.
Also:

this.ActiveControl = tsBox.Owner;
02.03.2007 - 11:29 Uhr
private struct printMyPrintData
{
   public Font NormalText;
   public SqlDataReader dr;
   public int Pages;
   public int Count;
}

private printMyPrintData pd;

private void printStromClick(object sender, EventArgs e)
{
   DialogResult buttonClicked = printDialog.ShowDialog();
   if (buttonClicked.Equals(DialogResult.OK))
   {
      printDocument.BeginPrint += new PrintPageEventHandler(printBegin);
      printDocument.PrintPage += new PrintPageEventHandler(printPage);
      printDocument.EndPrint += new PrintPageEventHandler(printEnd);
      printDocument.Print();
   }
}

private void printBegin(object sender, PrintEventArgs e)
{
   try
   {
      dataConnectRead = new SqlConnection();
      OpenDatabase(dataConnectRead);
      SqlCommand dataCommand = new SqlCommand();
      dataCommand.Connection = dataConnectRead;
      dataCommand.CommandText = "SELECT Datum, Uhrzeit, Strom FROM stromwerte ORDER BY Uhrzeit";
      pd.NormalText = new Font("Arial", 12);
      pd.dr = dataCommand.ExecuteReader();
      pd.Pages = 1;
      pd.Count = 0;
   }
   catch (Exception ex)
   {
      MessageBox.Show(this, ex.Message, "Fehler beim Zugriff auf die Datenbank");
      e.Cancel = true;
   }
   finally
   {
      dataCommand.Dispose();
      CloseDatabase(dataConnectRead);
   }
}

private void printEnd(object sender, PrintEventArgs e)
{
   pd.NormalText.Dispose();
   pd.NormalText = null;
   pd.dr.Close();
   pd.dr.Dispose();
   pd.dr = null;
   pd.Pages = 0;
   pd.Count = 0;
}

private void printPage(object sender, PrintPageEventArgs e)
{
   int lines = 0;
   float lineHeight = pd.NormalText.GetHeight(e.Graphics);
   int linesPerPage = (int)(e.MarginBounds.Height / lineHeight);
   int dataAvailable = dr.HasRows;

   float xpos = e.MarginBounds.Left;
   float yPos = e.MarginBounds.Top + lineHeight;

   while ((lines < linesPerPage) && dataAvailable)
   {
      string datum = pd.dr.GetString(0);
      string uhrzeit = pd.dr.GetString(1);
      int strom = pd.dr.GetInt32(2);
      string output = datum + "    |    " + uhrzeit + "    |    " + strom.ToString();
      e.Graphics.DrawString(output, printFont, Brushes.Black, xpos, yPos);
      yPos += lineHeight;
      lines++;
      pd.Count++;
      dataAvailable = pd.dr.Read();
   }

   if (dataAvailable)
   {
      e.HasMorePages = true;
      pd.Pages++;
   }
   else
   {
      e.HasMorePages = false;
      string output = "Insgesamt " + pd.Count.ToString() + " Datensätze";
      output += (pd.Pages == 1) ? String.Empty : (" auf " + pd.Pages.ToString() + " Seiten.");
      e.Graphics.DrawString(output, printFont, Brushes.Black, xpos, yPos);
   }
}

Weiters Beispiel siehe:Druckvorschau ist gut - Ausdruck ist leer

02.03.2007 - 10:42 Uhr

Es gibt keinerlei Aussagen darüber, wann DataReceived ausgelöst wird.
Wenn deine Anwendung jetzt Daten in einem ganz bestimmten Format erwartet, musst du zwischen Anwendung und Empfänger eine weitere Schicht einbauen, die die Daten aufbereitet: zwischenspeichern, synchronisieren (Anfang eines Blocks finden), formatieren (in 12Byte Blöcke zerlegen), kompletten Datensatz (also einen 12Byte Block) weitergeben, diesen Datensatz aus dem Zwischenspeicher entfernen (siehe auch Queue).

Das bedeutet also: deine Anwendung registriert einen Eventhandler bei der Zwischenschicht. Dieser wird eingebunden, wenn ein Datensatz bereit steht.

02.03.2007 - 10:31 Uhr

Klingt, als wäre das System voll ausgelastet, sobald der Fehler auftritt. Schau mal bitte im Taskmanager, welcher Prozess dort 99%-Auslastung hat...

02.03.2007 - 10:02 Uhr

Das blockieren einer GUI ist sehr schlecht, nicht weil dem User dann die Kontrolle genommen wird, sondern weil dann benötigte Events zum zeichnen der Form einfach nicht ausgeführt werden können und somit kann es u. a. passieren, dass der User auf einmal eine "weiße" Form hat.

Noch schlimmer ist eigentlich, dass alle Events weiterhin von Windows in die MessageLoop gestellt werden. Sobald die Aktion jetzt beendet ist, werden alle diese Events ganz hastig abgespult, ohne das der Nutzer zwischendurch eingreifen könnte.
So kann der gelangweilte, nervöse User durch ein paar unglückliche Klicks an ungünstige Stellen in das weiße Fenster sich sehr viel Arbeit machen.
Natürlich wird er aber berechtigterweise der Software die Schuld geben (und diese wohl nie wieder einsetzen, geschweige denn kaufen).

02.03.2007 - 09:39 Uhr

Beim Aufruf von http://www.mycsharp.de/wbb2/thread.php?postid=178232#post178232 (Link erhalten über "neue Beiträge") habe ich jetzt mehrfach folgende Fehlermeldung erhalten:

Fatal error: Maximum execution time of 30 seconds exceeded in /www/htdocs/v030194/wbb2/acp/lib/class_parse.php on line 510