| |
VB.NET - Ein- und UmsteigerRe: Backgroundworker mit eigenem Formular? | | | Autor: Bismosa | Datum: 15.07.11 08:26 |
| Hallo!
Vielen Dank für das Beispiel! Ich bin echt begeistert!
Da wäre ich so nie drauf gekommen. Ich merke daran auch, das ich echt ein stümper bin beim Programmieren. Mir fehlt da echt noch einiges an Grundlagen und Erfahrungen. Ich habe bestimmt jetzt 3h gebraucht um die Zusammenhänge zu verstehen. Aber je länger ich mir das anschaue, desto logischer wird es auch.
Würdest Du denn jetzt an meiner Stelle einen zusätzlichen Timer einbauen, falls keine Rückmeldung kommt?
So in etwa:
Protected Sub StartCommand(ByVal command As Command.CommandState)
Me.Enabled = False
StateTimer.Stop()
ErrorTimer.Stop()
ActState = CommandFactory.GetCommand(command, document)
StateTimer.Interval = ActState.TimeOut
ErrorTimer.Interval = 10000
document.Open()
PrintState(ActState, document)
StateTimer.Start()
ErrorTimer.Start()
End Sub
......
Private Sub ErrorTimer_Tick(ByVal sender As Object, ByVal e As _
System.EventArgs) Handles ErrorTimer.Tick
ErrorTimer.Stop()
If MsgBox("Abbrechen?", MsgBoxStyle.OkCancel) = MsgBoxResult.Ok Then
Me.Enabled = true
StateTimer.Stop()
Else
ErrorTimer.Start()
End If
End Sub Vielen Dank für die Mühe! Ich habe sehr viel gelernt daraus!
Gruß
Bismosa | |
Backgroundworker mit eigenem Formular? | | | Autor: Bismosa | Datum: 12.07.11 16:37 |
| Hallo!
Vielleicht ist mein Vorhaben ja ungewöhnlich...aber ich versuche es trotzdem...
Ich habe eine Schleife, die auf Beendung mittels einer Variablen wartet.
EDrawings.AxEModelViewControl1.OpenDoc(...)
Do Until EDrawings.Geladen = True
If EDrawings.geladenFehler = True Then
Me.Cursor = Cursors.Default
Exit Sub
End If
Application.DoEvents()
System.Threading.Thread.Sleep(100)
Loop Unter bestimmten Umständen kommt es immer mal wieder vor, dass ich diese Rückmeldung nicht bekomme, da eDrawings (Zeichnungsanzeige von SolidWorks) mir leider nicht mitteilt, wenn es einen Fehler beim Öffnen gab.
Daher habe ich vor, noch eine zeitschleife mit einzubringen, die nach 10sek. ein Eingabefeld anzeigt, dass es Probleme gibt und bestätigt werden möchte.
Wenn das Formular angezeigt wird (mit der Problembeschreibung) soll trotzdem weiter auf die Antwort gewartet werden und ggf. das Formularfenster automatisch geschlossen werden.
Versucht habe ich es, indem ich ein Backgroundworker benutze:
EDrawings.AxEModelViewControl1.OpenDoc(...)
Do Until EDrawings.Geladen = True
Try
LoopAbbruchZeit = 100
BGWLoopabbruch.RunWorkerAsync()
Catch ex As Exception
End Try
If LoopAbbruch = True Then
LoopAbbruch = False
Exit Sub
End If
If EDrawings.geladenFehler = True Then
Me.Cursor = Cursors.Default
Exit Sub
End If
Application.DoEvents()
System.Threading.Thread.Sleep(100)
Loop Und der backgroundworker:
Dim StartLoop As Date = System.DateTime.Now
Do
If CInt(System.DateTime.Now.Subtract(StartLoop).TotalMilliseconds) _
> LoopAbbruchZeit Then
If Not LoopabbruchDialog.Visible = True Then
LoopabbruchDialog.Show(Me)
End If
End If
If BGWLoopabbruch.CancellationPending = True Then
Exit Sub
End If
If LoopAbbruch = True Then
Exit Sub
End If
System.Threading.Thread.Sleep(200)
Loop Das Dialogfeld wird jedoch nicht angezeigt. Je nach Timing noch ohne Steuerelemente und wenn dann schon gar nicht bedienbar. Kann ich denn in einem 2.Prozess kein eigenes Fenster bekommen?
Ich habe auch schon daran gedacht, die eigentliche Schleife auszulagern. Hier bekomme ich jedoch probleme, da ich im Formular "EDrawings" von meinem Hauptformular aus arbeite. Ich muss ja auch die Rückmeldung bekommen...
Mache ich vielleicht einen grundsätzlichen Denkfehler?
Gruß
Bismosa | |
Re: Backgroundworker mit eigenem Formular? | | | Autor: FZelle (Moderator) | Datum: 12.07.11 16:40 |
| Nein, du darfst nur vom UI Thread aus ein Fenster oder UI Elemente erstellen.
Auch würde ich dafür keinen Thread verschwenden, sondern einen Timer benutzen. | |
Re: Backgroundworker mit eigenem Formular? | | | Autor: Bismosa | Datum: 13.07.11 07:58 |
| Hallo!
Danke für den Tip. Mit einem Timer funktioniert es.
EDrawings.AxEModelViewControl1.OpenDoc(...)
TimerLoopAbbruch.Interval = 10000
TimerLoopAbbruch.Start()
Do Until EDrawings.Geladen = True
If LoopAbbruch = True Then
LoopAbbruch = False
Exit Sub
End If
If EDrawings.geladenFehler = True Then
Me.Cursor = Cursors.Default
Exit Sub
End If
Application.DoEvents()
System.Threading.Thread.Sleep(100)
Loop
TimerLoopAbbruchFertig() Und der Timer:
Private Sub TimerLoopAbbruch_Tick(ByVal sender As Object, ByVal e As _
System.EventArgs) Handles TimerLoopAbbruch.Tick
If Not LoopabbruchDialog.Visible = True Then
LoopabbruchDialog.Show(Me)
End If
End Sub
Public Sub TimerLoopAbbruchFertig()
TimerLoopAbbruch.Stop()
If LoopabbruchDialog.Visible = True Then
LoopabbruchDialog.Close()
End If
End Sub Ich denke mal, das Du es so meintest?
Danke!
Gruß
Bismosa | |
Re: Backgroundworker mit eigenem Formular? | | | Autor: FZelle (Moderator) | Datum: 13.07.11 09:58 |
| Äh, da hast du aber etwas falsch verstanden.
Das ist aber nicht, wie man einen Timer benutzen sollte.
Ich meinte eher das Du im Timer deine Aktion ausführst. | |
Re: Backgroundworker mit eigenem Formular? | | | Autor: Bismosa | Datum: 13.07.11 12:39 |
| Hallo!
Hmmm...dann stehe ich jetzt aber total auf dem Schlauch. Ich habe keine Ahnung, wie Du das meinst.
Kannst mir da noch auf die Sprünge helfen?
Gruß
Bismosa | |
Re: Backgroundworker mit eigenem Formular? | | | Autor: FZelle (Moderator) | Datum: 13.07.11 12:51 |
| Einen Timer benutzt man um regelmässig eine Aktion durchzuführen.
Du startest also den Timer und testest im Timer.Tick ob die Var gesetzt ist und führst dann eine Aktion aus.
Endlosschleifen macht man nicht. | |
Re: Backgroundworker mit eigenem Formular? | | | Autor: Bismosa | Datum: 13.07.11 16:31 |
| Hallo!
Irgendwie verstehe ich es leider immer noch nicht.
Ich will doch mit dem Timer prüfen, ob ich immer noch in der Schleife bin und auf meine Var warte. Wenn dies so ist, dann möchte ich ein Dialogfeld haben, mit dem ich die Schleife bei bedarf unterbrechen kann.
Ist die Schleife beendet, bevor der User abbricht, verschwindet das Dialogfeld wieder.
Wie ich es hinbekommen soll, ohne eine Endlosschleife zu machen weiß ich nicht. Ich könnte sonst einen Wert bei jedem Durchlauf der Schleife hochzählen und wenn ein gewisser Wert erreicht ist (also die Zeit abgelaufen ist) ein Dialogfeld anzeigen...dann wird aber während das Dialogfeld offen ist, nicht weiter geprüft, ob die Var mittlerweile gesetzt wurde.
Vielleicht fehlen mir auch noch andere Grundlagen des Programmierens?
Gruß
Bismosa | |
Re: Backgroundworker mit eigenem Formular? | | | Autor: Maas | Datum: 13.07.11 18:57 |
| Stell dir den Timer als deine Endlosschleife vor. In deiner Schleife hast du ja ein Sleep von 100. Das ist dann Timer.Interval = 100. Alles was du in der Schleife machst, machst du dann im Timer. Die Schleife an sich fällt komplett weg (das Application.DoEvents auch).
Maas | |
Re: Backgroundworker mit eigenem Formular? | | | Autor: Bismosa | Datum: 14.07.11 08:20 |
| Hallo!
Der Groschen fällt in Pfennigen
Ich habe bisher eine Sub in der folgendes ausgeführt wird:
- Öffnen des Dokumentes
- Warten (Do...Loop) bis Dokument geöffnet
- Drucken des Dokumentes
- Warten (Do...Loop) bis Dokument gedruckt
- Schließen des Dokumentes
- Warten (Do...Loop) bis Dokument geschlossen
Wenn ich das mit Timern umsetzen würde, würde es in etwa so aussehen:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles Button1.Click
'Dokument öffnen
Timer1.Interval = 100
Timer1.Start()
End Sub
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles Timer1.Tick
If Var1 = True Then 'Dokument geöffnet
Timer1.Stop()
'Drucken...
Timer2.Interval = 100
Timer2.Start()
End If
End Sub
Private Sub Timer2_Tick(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles Timer2.Tick
If Var2 = True Then
Timer2.Stop()
'Dokuent schließen...
Timer3.Interval = 100
Timer3.Start()
End If
End Sub
Private Sub Timer3_Tick(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles Timer3.Tick
If Var3 = True Then
Timer3.Stop()
MsgBox("Operation abgeschlossen.")
End If
End Sub Bekomme ich z.B. nach dem Drucken keine Rückmeldung (passiert leider immer mal wieder...warum weiß ich allerdings nicht...) hänge ich trotzdem fest. Solange diese Prozedur läuft, ist die Form gesperrt, da andere Dokumente während dessen nicht angefordert werden können.
Also noch einen 4. Timer, der dann den Abbruch auslöst, wenn es zu lange dauert?
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles Button1.Click
'Dokument öffnen
Timer1.Interval = 100
Timer1.Start()
Timer4.Interval = 10000
Timer4.Start()
End Sub
Private Sub Timer4_Tick(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles Timer4.Tick
If MsgBox("Abbrechen?", MsgBoxStyle.OkCancel) = MsgBoxResult.Ok Then
Timer1.Stop()
Timer2.Stop()
Timer3.Stop()
Timer4.Stop()
End If
End Sub War das denn jetzt so gemeint? Ich finde, das der Code so nicht wirklich übersichtlicher wird. Gerade da ich ähnliche Abfolgen zu hauf schon im Programm habe. Es werden dann viele Timer benötigt. Allerdings bekomme ich so das (wohl recht gehasste) Application.doevents weg.
Und wenn ihr so etwas vorschlagt, dann muss da was dran sein!
Gruß
Bismosa | |
Re: Backgroundworker mit eigenem Formular? | | | Autor: FZelle (Moderator) | Datum: 14.07.11 11:22 |
| Anhang: stateDemo.ZIP (13k) |
| Naja, man kann ja auch das eine oder andere Wiederverwenden.
Das was du hier hast ist eine klassische Statemaschine.
Du hast also verschiedene Zustände die ineinander übergehen können und die Zeit oder Aktions gesteuert sind.
Ist zwar im ersten Moment etwas mehr arbeit aber du wirst sehen das ist viel übersichtlicher und wartbarer. | |
Re: Backgroundworker mit eigenem Formular? | | | Autor: FZelle (Moderator) | Datum: 15.07.11 10:10 |
| Da bist du nicht der einzige.
Viele glauben das es reicht "ein bisschen" logisch denken zu können, aber wissen nicht das
ein "paar" Grundlagen wie Pattern oder OOP helfen viele Sachen einfacher zu lösen.
Ich würde dann eher noch MaximaleVersuche in das Command einbauen.
Dann kannst du auch darüber steuern wie lange der ErrorTimeout läuft.
Das Öffnen der Datei kann somit z.b. früher abgebrochen werden als ein Ausdruck von 50 Seiten. | |
| Sie sind nicht angemeldet! Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.
Einloggen | Neu registrieren |
|
|
sevAniGif (VB/VBA)
Anzeigen von animierten GIF-Dateien
Ab sofort lassen sich auch unter VB6 und VBA (Access ab Version 2000) animierte GIF-Grafiken anzeigen und abspielen, die entweder lokal auf dem System oder auf einem Webserver gespeichert sind. Weitere InfosTipp des Monats TOP Entwickler-Paket
TOP-Preis!!
Mit der Developer CD erhalten Sie insgesamt 24 Entwickler- komponenten und Windows-DLLs. Die Einzelkomponenten haben einen Gesamtwert von 1605.50 EUR...
Jetzt nur 599,00 EURWeitere Infos
|