2016-07-28 7 views
0

Ich habe ein Formular, dessen Rolle es ist, dem Benutzer eine kreisförmige Fortschrittsgrafik zu zeigen, während der Benutzer auf bestimmte Sachen wartet. Dies ist der einfache Code davon:Aufgabenfunktion in Formular- und Fehlermeldungen

Public Class FrmCircularProgress 
    Sub New(progressType As DevComponents.DotNetBar.eCircularProgressType) 
     InitializeComponent() 
     CircularProgress1.ProgressBarType = progressType 
     StartCircular() 
    End Sub 

    Public Sub StartCircular() 
     Me.CircularProgress1.IsRunning = True 
    End Sub 

    Public Sub StopCircular() 
     Me.CircularProgress1.IsRunning = False 
    End Sub 
End Class 

Unten ist ein Beispiel dafür, wie ich es verwenden (in diesem Fall zwei Stellen)

Dim createArticle As New Artikel 

        'http://stackoverflow.com/questions/33030706/put-long-running-method-into-task-showing-new-form-meantime-and-closing-it-once 
        Dim pic As New FrmCircularProgress(eCircularProgressType.Donut) 
        Dim tsk As Task(Of Boolean) = Task.Factory.StartNew(Of Boolean)(Function() 
                         '--Run lenghty task 
                         Dim resu = False 
                         Try 
                          resu = createArticle.ProcessArticle(_artikelsAndTheirVariationsFinal) 
                          '--Close form once done (on GUI thread) 

                         Catch sqlex As Exception 
                          pic.Invoke(Sub() MessageBox.Show(pic, sqlex.Message)) 
                          ' pic.Invoke(Sub() MessageBox.Show(pic, ex.Message)) 
                          'pic.Invoke(Sub() TaskDialog.Show(pic, New TaskDialogInfo("Information", eTaskDialogIcon.BlueStop, "WizardPageDescriptionUberblick_BeforePageDisplayed", ex.ToString, eTaskDialogButton.Ok, eTaskDialogBackgroundColor.Blue, Nothing, Nothing, Nothing, "Jakis footer text", Nothing))) 
                         Finally 

                         End Try 

                         pic.Invoke(New Action(Sub() pic.StopCircular())) 
                         pic.Invoke(New Action(Sub() pic.Close())) 
                         Return resu 
                        End Function) 

        '--Show the form 
        pic.ShowDialog() 
        Task.WaitAll(tsk) 

        If tsk.Result = True Then 
         TaskDialog.Show(New TaskDialogInfo("Information", eTaskDialogIcon.BlueStop, "Infor", "New articel and every data has been added correctly", eTaskDialogButton.Ok, eTaskDialogBackgroundColor.Blue, Nothing, Nothing, Nothing, "Jakis footer text", Nothing)) 

         'http://stackoverflow.com/questions/33030706/put-long-running-method-into-task-showing-new-form-meantime-and-closing-it-once 
         pic = New FrmCircularProgress(eCircularProgressType.Line) 
         Dim work As Task = Task.Factory.StartNew(Sub() 
                    '--Run lenghty task 
                    PrepareUberblick() 
                    '--Close form once done (on GUI thread) 
                    pic.Invoke(New Action(Sub() pic.StopCircular())) 
                    pic.Invoke(New Action(Sub() pic.Close())) 
                   End Sub) 

         '--Show the form 
         pic.ShowDialog() 
         Task.WaitAll(work) 

         If WYSWIG_Uberblick.Document IsNot Nothing Then 
          WYSWIG_Uberblick.Document.Write(String.Empty) 
         End If 

         '--Pobranie wszystkich html'ow wszystkich podsekcji artykulow (w tym wypadku numerów artykułów jako podsekcji) (dla sekcji Uberblick) 
         WYSWIG_Uberblick.DocumentText = _htmlFactory.GetAllUberblickHTML 
        Else 
         TaskDialog.Show(New TaskDialogInfo("Information", eTaskDialogIcon.NoEntry, "Infor", "Critical error occured", eTaskDialogButton.Ok, eTaskDialogBackgroundColor.Blue, Nothing, Nothing, Nothing, "Jakis footer text", Nothing)) 
         e.Cancel = True 
        End If 

ProcessArticle Funktion:

Public Function ProcessArticle(artikel As ArticlesVariations) As Boolean 

     Dim result = True 
     Dim strcon = New AppSettingsReader().GetValue("ConnectionString", GetType(System.String)).ToString() 

     Using connection As New SqlConnection(strcon) 
      '-- Open generall connection for all the queries 
      connection.Open() 
      '-- Make the transaction. 
      Dim transaction As SqlTransaction 
      transaction = connection.BeginTransaction(IsolationLevel.ReadCommitted) 

      Dim newArticleRowId As Integer = 0 
      Dim articleIndex As Integer = 0 
      Try 
       For Each kvp As KeyValuePair(Of Integer, Artikel) In artikel.collection 
        Dim ckey As Integer = kvp.Key 
        articleIndex = kvp.Key    'save article key 
        Dim data As Artikel = kvp.Value 

        '-- If given article contains images list (artikel_images is a list with pictures associated with article) 
        If Not IsNothing(artikel.collection(articleIndex).ArtikelImages) Then 
         For Each img In artikel.collection(articleIndex).ArtikelImages 
          '--Insert article's images if exists 
          Using cmd As New SqlCommand("INSERT INTO T_Article_Image (Path, FK_Artikel_ID, Position) VALUES (@Path, @FK_Artikel_ID, @Position)", connection) 
           cmd.CommandType = CommandType.Text 
           cmd.Connection = connection 
           cmd.Transaction = transaction 
           cmd.Parameters.AddWithValue("@Path", img.Path) 
           cmd.Parameters.AddWithValue("@FK_Artikel_ID", newArticleRowId) 
           cmd.Parameters.AddWithValue("@Position", img.Position) 
           cmd.ExecuteScalar() 
          End Using 
         Next 
        End If 

        '-- If given article contains articles variations list (artikel_variation_attributes is a list with variations associated with article) 
        If Not IsNothing(artikel.collection(articleIndex)._artikel_variation_attributes) Then 
         For Each var In artikel.collection(articleIndex)._artikel_variation_attributes 

          '--Insert article's images if exists 
          Using cmd As New SqlCommand("INSERT INTO T_Artikel_T_Variation (FK_Variation_VariationAttribute_ID, FK_Artikel_ID, Position) VALUES (@FK_Variation_VariationAttribute_ID, @FK_Artikel_ID, @Position)", connection) 
           cmd.CommandType = CommandType.Text 
           cmd.Connection = connection 
           cmd.Transaction = transaction 
           cmd.Parameters.AddWithValue("@FK_Variation_VariationAttribute_ID", New Variation_VariationAttribute(var.FkVariationId, var.FkVariationAttributeId).GetId()) 
           cmd.Parameters.AddWithValue("@FK_Artikel_ID", newArticleRowId) 
           cmd.Parameters.AddWithValue("@Position", var.Position) 
           cmd.ExecuteScalar() 
          End Using 
         Next 
        End If 

       Next 
       transaction.Commit() 
      Catch ex As Exception 
       result = False 
       '-- Roll the transaction back. 
       Try 
        transaction.Rollback() 
       Catch ex2 As Exception 
        ' This catch block will handle any errors that may have occurred 
        ' on the server that would cause the rollback to fail, such as 
        ' a closed connection. 
        'Console.WriteLine("Rollback Exception Type: {0}", ex2.GetType()) 
        'Console.WriteLine(" Message: {0}", ex2.Message) 
       End Try 

      End Try 
     End Using 

     Return result 
    End Function 

alles funktioniert wenn es um Fehler oder was auch immer innerhalb dieser Methoden (von unserem Beispiel) kommt:

Dim resu As Boolean = createArticle.ProcessArticle(_artikelsAndTheirVariationsFinal) 

oder diese Methode:

PrepareUberblick() 

Meine circural Form schließt nicht, aber es läuft noch (es festsitzt). Wenn ich Alt+F4 mache, um meine zirkuläre Form zu töten, sehe ich eine Fehlermeldung. Ich nehme an, dass wenn ein Fehler auftritt, das Fehlermeldungsfenster nicht im Vordergrund angezeigt wird, sondern hinter dem Kreisformular verborgen ist.

Hier ist die Frage: Wissen Sie, wie Sie es beheben können? Wenn ein Fehler auftritt, wird eine Fehlermeldung angezeigt, damit der Benutzer bestätigen kann und das Kreisformular geschlossen wird?

+0

Was ist der Fehler Botschaft? – Tim

+0

es ist über spezifische Funktion, die ich verwende. In diesem Fall, wenn ein Fehler aus Dim resu As Boolean = createArticle.ProcessArticle (_artikelsAndTheirVariationsFinal) oder in einem zweiten PrepareUberblick() herauskommt, wird der Fehler über diesen sein. Es ist mehr wie egal, welcher Fehler geht es darum, wie es geht Fügen Sie zusätzlichen Code hinzu, um die aktuelle Implementierung meiner Zirkulationsnutzung zu verbessern. Wenn also Fehler in der Aufgabe auftreten, wie man sie vor der App zeigt und nicht dahinter, würde ich das Zirkulationsformular nicht töten müssen, um es zu sehen. –

Antwort

0

Wenn Sie den Benutzer darauf hinweisen möchten, dass etwas passiert ist, können Sie die MessageBox von Ihrem Rundschreiben aus anzeigen, das darüber angezeigt werden soll, da es im selben Thread generiert wird. Sie können in der Catch

Try 
    '--Run lenghty task 
    resu = createArticle.ProcessArticle(_artikelsAndTheirVariationsFinal) 
Catch ex As Exception 
    pic.Invoke(Sub() MessageBox.Show(ex.message)) 
End Try 
'--Close form once done (on GUI thread)   
pic.Invoke(New Action(Sub() pic.StopCircular())) 
pic.Invoke(New Action(Sub() pic.Close())) 

diese Weise wird die MessageBox zeigen, wird der Benutzer auf der MessageBox klicken müssen OK, bevor der Kreisform geschlossen wird.

Ihr gesamtes Problem rührt von der Tatsache her, dass Sie MessageBox.Show() nicht für denselben Thread aufgerufen haben, für den das Formular erstellt wurde. Aus dem Beispiel, in dem das Formular erstellt wird, geht nicht klar hervor, ob es sich um den UI-Thread handelt oder nicht. In beiden Fällen muss der Thread, auf dem das Formular erstellt wird, der gleiche sein, auf dem das Meldungsfeld ausgelöst wird, damit die MessageBox modal für das Formular sein kann. Wenn Sie pic.Invoke(Sub() MessageBox.Show(ex.message)) aufrufen, stellen Sie sicher, dass es im Thread des Formulars angezeigt wird und modal ist. Sie können in der Regel das übergeordnete Fenster erzwingen, indem die overload verwendet, die

Public Shared Function Show (
    owner As IWin32Window, 
    text As String 
) As DialogResult 

die

pic.Invoke(Sub() MessageBox.Show(pic, ex.message)) 

auch sehen würde hat:

Does MessageBox.Show() automatically marshall to the UI Thread?

Why use a owner window in MessageBox.Show?

+0

meinst du, wenn ich msgbox (ex.tostring) in diesem catch statment wird es dem Benutzer oben auf diesem Zirkularformular gezeigt werden? und wird es als nächstes von Task.WaitAll (tsk) gehen oder es würde auch dort hängen Ist es auch möglich von deiner Seite zu zeigen, wie man solche struct in diesem Fall implementiert? –

+0

Es wird nicht im Formular angezeigt, da es von einer Aufgabe generiert würde, d. H. Nicht vom UI-Thread. Siehe http://stackoverflow.com/questions/559252/does-messagebox-show-automatical-marshall-to-the-ui-thread. Aber Sie könnten vielleicht eine Methode in die zirkuläre Form bringen, die Sie im Fehlerfall aufrufen könnten. Ich werde meine Antwort bearbeiten. – djv

+0

Hallo, danke an erster Stelle. Haben Sie noch Probleme, Ihre Lösung zu implementieren. Die Situation ist wie folgt: Haben Hauptform, in der ich Benutzerkontrolle setzte und auf diesem Benutzersteuerelement habe ich etwas Zaubererkontrolle, also kann ich zurück/als nächstes tun. Und dieses Rundschreibenformular wird auf Zauberer gelegt (so Benutzerkontrolle). Wenn ich das nur benutze: pic.Invoke (Sub() MessageBox.Show (pic, ex.message)) sehe ich keine Fehlermeldung (ich habe überprüft, dass einige falsche Mitarbeiter). Ich gehe davon aus, dass ich auch überladen muss, wie du Show auf meiner Benutzerkontrolle erwähnst, aber was soll darin funktionieren? Kannst du mir damit helfen? –

Verwandte Themen