asynchrone Datenbankabfragen

03/09/2009 - 15:27 von Stefan Simon | Report spam
Hallo,

ich habe eine dll, die Datenbankabfragen durchführt. Eine
WindowsForms-Anwendung übergibt der dll SQL Statements und soll anschließend
weitermachen. Asynchron sollen die Abfragen deshalb sein, damit die
Oberflàche nicht einfriert. z.B. habe ich eine Progressbar, die permanent
durchlàuft, bis die Abfrage abgeschlossen ist. Damit die Form reagiert, habe
ich folgendes in die dll, implementiert:
public Int32 ExecuteAsync()
{
RowCount = -1;
Execute(HandleCallback);
while (RowCount < 0)
{
System.Windows.Forms.Application.DoEvents();
//System.Threading.Thread.Sleep(50);
}
if (LastError != null)
{
throw LastError;
}
return RowCount;
}

Das DoEvents() sorgt dafür, dass die Progressbar wàhrend der Abfrage
aktualisiert wird. Allerdings hat das einen Nebeneffekt. Andere Ereignisse
werden ebenfalls verarbeitet, etwa SplitterMoved und ColumnWidthChanged, bei
deren Eintreten ebenfalls Datenbankabfragen ausgeführt werden und zu
unerwartetem und ungewollten Verhalten führen (z.B. kann man den Splitter
nur einmal verschieben, danach kann man ihn nicht mehr anfassen).

Ich habe das Verhalten bis zu DoEvents() zurück verfolgen können, weiß nun
aber nicht, womit ich das ersetzen kann. Auskommentieren reicht nicht, da
damit die Progressbar im aufrufenden Form nicht aktualisiert wird.

Wie könnte man das Problem lösen?

tia
Stefan
 

Lesen sie die antworten

#1 Frank Dzaebel
03/09/2009 - 22:12 | Warnen spam
Hallo Stefan,

ich habe eine dll, die Datenbankabfragen durchführt. Eine
WindowsForms-Anwendung übergibt der dll SQL Statements und soll
anschließend weitermachen. Asynchron sollen die Abfragen deshalb
sein, damit die Oberflàche nicht einfriert. z.B. habe ich eine
Progressbar, die permanent durchlàuft, bis die Abfrage abgeschlossen
ist.



ok, im Prinzip also soetwas:

[SqlCommand.BeginExecuteNonQuery-Methode (System.Data.SqlClient)]
http://msdn.microsoft.com/de-de/lib...6w9se.aspx

[Galileo Computing :: Visual C# 2008 - 26.4 Asynchrone Abfragen]
http://openbook.galileocomputing.de...26_004.htm

[CodeProject: Asynchronous data loading and data binding with Windows Forms]
http://www.codeproject.com/KB/miscc...ading.aspx

[How to populate the datagrid on background thread with data binding by
using Visual C#]
http://support.microsoft.com/kb/318607/en-us

[Bearbeiten von Steuerelementen aus Threads]
http://dzaebel.net/ControlInvoke.htm



Das DoEvents() sorgt dafür, dass die Progressbar wàhrend der Abfrage
aktualisiert wird. Allerdings hat das einen Nebeneffekt. Andere
Ereignisse werden ebenfalls verarbeitet, etwa SplitterMoved und
ColumnWidthChanged, bei deren Eintreten ebenfalls Datenbankabfragen
ausgeführt werden und zu unerwartetem und ungewollten Verhalten
führen (z.B. kann man den Splitter nur einmal verschieben, danach
kann man ihn nicht mehr anfassen).



Also DoEvents hast Du hier ungünstig eingesetzt.
Das eigentliche, was Du willst, ist eben, dass wàhrend des
"Long Work" nicht andere Controls aktualisiert werden sollen,
sondern nur Deine ProgressBar.

Nun, da gibt es mehrere Ansàtze. Du könntest natürlich
die entsprechenden unerwünschten Controls in dieser
Zeit auf "*.Enabled = false" setzen und am Ende wieder zurück.
Andere Ansàtze sind:

http://groups.google.de/group/micro...61b9754557
http://groups.google.com/group/micr...8e3f5bfbea

Oder aber nicht DoEvents aufrufen, sondern ein
eigenes DoEvents, wobei Du dann vor DispatchMessage
prüfst, ob "msg.wParam == progressBar1.Handle" ist und
nur dann die Message disatch'st. Eine Behandlung im
überschriebenen WndProc würde hier übrigens nicht ausreichend sein.

[C# Lesson 1: The Main Loop « Real Time Software Rendering]
http://code.dawnofthegeeks.com/2009...main-loop/
(Hier sollte man "System.WIndows.Forms.Message" benutzen)


ciao Frank
Dipl.Inf. Frank Dzaebel [MCP/MVP C#]
http://Dzaebel.NET

Ähnliche fragen