Autor Beitrag
new.Matrix
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 56



BeitragVerfasst: Di 17.06.08 14:38 
Hallo Zusammen,

Ich habe nun meine Software fertig entwickelt und sie läuft auch einwandfrei. Nun möchte ich noch einige Schönheistmakel beseitigen. Darunter habe ich auch folgendes Problem:
Meine Software besteht aus einer Auswertung, die einige Zeit in Anspruch nimmt, da viele Artikel ausgewertet werden müssen. Dabei habe ich einen Progressbar, welcher den aktuellen Status anzeigt. Bis jetzt habe ich dabei auf eine Zwischenlösung zurückgegriffen, da ansonsten das Fenster bis zum Schluss der Auswertung nicht neu gezeichnet wurde und zwar mithilfe diese codes:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
private static System.Windows.Threading.DispatcherOperationCallback exitFrameCallback = new
             System.Windows.Threading.DispatcherOperationCallback(ExitFrame);

        private static Object ExitFrame(Object state)
        {
            System.Windows.Threading.DispatcherFrame frame = state as System.Windows.Threading.DispatcherFrame;

            frame.Continue = false;
            return null;
        }

        public static void DoEvents()
        {
            System.Windows.Threading.DispatcherFrame nestedFrame = new System.Windows.Threading.DispatcherFrame();

           
            System.Windows.Threading.DispatcherOperation exitOperation = System.Windows.Threading.Dispatcher.CurrentDispatcher.BeginInvoke(
                System.Windows.Threading.DispatcherPriority.Background, exitFrameCallback, nestedFrame);


            System.Windows.Threading.Dispatcher.PushFrame(nestedFrame);

            if (exitOperation.Status != System.Windows.Threading.DispatcherOperationStatus.Completed)
            {
                exitOperation.Abort();
            }
        }


Nun ist es zum Einten keine schöne Lösung und zum Anderen wirkt das Programm wie eingefroren, bis der nächste Artikel ausgewertet wird, denn dann wird erst das Fenster neu gezeichnet. Wie kann ich es lösen, dass jederzeit das Fenster angeklickt werden kann und dieses auch erscheint mit Statusanzeige?
Ich habe nun schon viel gelesen, nin aber noch ein Newbee und blicke langsam nicht mehr durch ob ich jetz backgroundworker oder Threading anwenden muss und wie ich am besten vorgehe...

Kann mir jemand helfen?
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Di 17.06.08 20:30 
Titel: Re: lange berechnung anzeige von Statusbar, Fenster eingefro
user profile iconnew.Matrix hat folgendes geschrieben:
Ich habe nun schon viel gelesen, nin aber noch ein Newbee und blicke langsam nicht mehr durch ob ich jetz backgroundworker oder Threading anwenden muss und wie ich am besten vorgehe...
Wenn du die Berechnung so in kleine Teile aufbrechen kannst, dass der User von einem Teil nichts merkt, nimmst du die "Dispatcher-Schleife", ansonsten Threads. Eine ausführliche Beschreibung zu beidem findest du unter "Threading Model [WPF]".

PS: Von DispatcherFrame höre ich heute zum ersten Mal :shock: .
PPS: Macht dir das eigentlich Spaß, jedes Mal den vollen Namespace zu tippen ;) ?
new.Matrix Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 56



BeitragVerfasst: Do 19.06.08 08:32 
Erstmals danke für die Antwort!

...meinst du Threading Model [WPF] in der SDK Doku?
Ich habe esch schon mit Threading versucht, bin aber daran gescheiter. Ich hatte die Berechnung in eine Methode ausgelagert und diese in der Schleife in einem Thread gestartet. Nur lief mir da die Schleife durch und die Berechnung hat es glaube ich nur einmal gemacht, aber ich werde mich mal weiterdurchlesen...

Zitat:
PPS: Macht dir das eigentlich Spaß, jedes Mal den vollen Namespace zu tippen ;) ?


Nee dieser Code hatte ich selbst von irgendwo aufgeschnappt, ich selbst bevorzuge using ;-)
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Do 19.06.08 11:07 
Ich weiß gerade nicht, ob C# schon Sprachelemente hat, die das Arbeiten mit Threads erleichtern. In Oxygene geht es so:
ausblenden Delphi-Prism-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
  var max := 1000//irgendein Wert für unsere Beispiel-Schleife
  progressBar1.Maximum := max; //Maximum der ProgressBar entsprechend setzen
  async begin
    for i : Integer := 0 to max do
    begin
      Thread.Sleep(100); //Stück der langen Berechnung

      Dispatcher.Invoke(DispatcherPriority.Normal, methodbegin
        progressBar1.Value := i; //Statusbar aktualisieren
      end);
    end;
  end;

Falls C# kein Äquivalent zum async-Statement hat, dann pack einfach alles von "async begin" bis zum letzten "end" in eine eigene Methode, die Du in einem eigenen Thread aufrufst. Der Rest sollte bis auf Syntax-Unterschiede genauso gehen.

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".
new.Matrix Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 56



BeitragVerfasst: Do 19.06.08 13:29 
Danke euch beiden! Habs nun mit der Hilfe zu Threading Modell der SDK Doku hinbekommen und zwar so:

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
   
public class Haupklasse{
     public delegate void DoCalculateDelegate();
     public delegate void UpdateDisplayDelegate();

        public Haupklasse()
        {
            InitializeComponent();
        }

        private void btnDoSomething_Click(object sender, RoutedEventArgs e)
        {
         // Sonstiger Code
         ...
         // EOF Sonstiger Code

          DoCalculateDelegate fetcher = new DoCalculateDelegate(this.DoCalculate);

          fetcher.BeginInvoke(nullnull);
         }

        public void DoCalculate()
        {
           for(i=0;i<anzahlberechnungen;i++)
           {

           // Hier grosse langandauernde Berechnung


           this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,new UpdateDisplayDelegate(UpdateUserInterface));
           }
        }

        private void UpdateUserInterface()
        {
            // Hier kann man auf die Elemente der benutzeroberfläche Zugreiffen
     
        }
}


Und das ists auch schon :-D einfach wenn man weiss wie...
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Do 19.06.08 14:19 
C# kann auch IIRC auch anonyme Methode und Delegates, die Du bei Dispatcher.Invoke aufrufen kannst. Dann brauchst Du keine eigene Methode im Code definieren.

_________________
Zwei Worte werden Dir im Leben viele Türen öffnen - "ziehen" und "drücken".