Autor Beitrag
mannyk
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 83
Erhaltene Danke: 1



BeitragVerfasst: Do 03.05.12 15:27 
Hallo,

ich weiß, das Thema wurde schon sehr oft gestellt, aber in meiner Situation haben mir die vielen Suchergebnisse nicht wirklich geholfen, da, wie ich das sehe, meine Anforderungen etwas speziell sind.

Deshalb möchte ich nun hier fragen:

Ich habe einen Thread, der in einer State-Maschine verschiedene Aufgaben abarbeitet. Das ganze kann man sich in
einer großen While-Schleife vorstellen, welche unendlich lang abgearbeitet wird. Die abzuarbeitenden Aufgaben holt sich der Thread aus einer Warteschlange ab.

Nun können in dieser Warteschlange Objekte auftreten, bei welchen der andere Thread (jener, der die Objekte in die Warteschlange einreiht) benachrichtigt werden muss.

Wie kann ich diesen Thread abhängig vom Objekt elegant benachrichtigen? Bislang mache ich das so, dass ich in dem betreffenden Objekt ein Flag setze und im anderen Thread solang warte, bis das Thread gesetzt wurde.
Was meint ihr zu dieser Lösung? Ich finde sie nicht so elegant.

Code-Schnipsel, wo gewartet wird, bis das Flag gesetzt wurde

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:
 while (true)
            {
                    // Hole die erste Message aus der Warteschlange
                    var message = InboundQueue.Dequeue();

                    // Falls Job schon besteht, leite Nachricht an passenden Job weiter
                    if (JobTable.Contains(info))
                    {
                        var job = JobTable[info];
                        // Markiert die Nachricht für den Testlauf, da nicht absehbar ist, ob die Nachricht zur Abfolge passt
                        message.TryUse = true;
                        message.RuleResult = Rules.RuleResult.Undefined;
                                                
                            // Einreihen in die Warteschlange des Jobs
                            job.InboundQueue.Add(message);

                            // Es wird gewartet, bis der Thread die Nachricht abarbeitet und das Flag bezg. des Status' setzt
                            while (message.RuleResult == Rules.RuleResult.Undefined)
                            {
                                Thread.Sleep(10);
                            }

                            switch (message.RuleResult)
                            {
                                case Rules.RuleResult.TestPassed:
                                    // Falls die Nachricht erfolgreich abgearbeitet wurde, kann gleich zur nächsten Nachricht gesprungen werden
                                    continue;
                                default:
                                    // Falls die Nachricht nicht abgearbeitet wurde, werden die Flags wieder rückgängig gemacht und es wird
                                    // versucht die Nachricht anderweitig zu verarbeiten
                                    message.RuleResult = Rules.RuleResult.Undefined;
                                    break;
                            }

                    }
                    message.TryUse = false;
            }


Code-Schnipsel, wo das Flag gesetzt wird:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
                        ruleResult = Rules.Validate(Rules.RuleName.Rule1a, message, out response, job);
                        message.RuleResult = ruleResult;
                        switch (ruleResult)
                        {
                            case Rules.RuleResult.Failed:
                                RemoveJob(job);
                                return;
                            case Rules.RuleResult.TestFailed:
                                continue;
                        }



Moderiert von user profile iconTh69: Topic aus C# - Die Sprache verschoben am Do 03.05.2012 um 15:55
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4795
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Do 03.05.12 15:54 
Hallo mannyk,

da gibt es wirklich bessere Synchronisierungsmethoden.
Zu den Stichwörtern Mutex, Semaphore, WaitHandle etc. solltest du dich mal einlesen - diese befinden sich alle im System.Threading-Namespace.

In deinem Fall würde ich einen AutoResetEvent verwenden und dessen Set sowie WaitOne-Methoden aufrufen.
mannyk Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 83
Erhaltene Danke: 1



BeitragVerfasst: Do 03.05.12 16:48 
Hallo und danke für deine Antwort,

ich hab bereits mit AutoResetEvent herumgespielt und würde es gerne einsetzen.
Allerdings hab ich bis jetzt keine Möglichkeit gefunden, wie ich über autoEvent.Set(); ein Objekt mitgeben kann und mit autoEvent.WaitOne(); darauf zugreifen kann.

Gibt es da eine Möglichkeit?

Danke und lg,
mannyk
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Do 03.05.12 17:13 
AutoResetEvent ist ein reines Schrankensystem damit übergibst du keine Daten zwischen Threads sondern synchronisierst nur den Ablauf. Von was für einem Object das du übergeben willst reden wir hier? Je nachdem was das für ein Ding ist müsstest du das Object selbst oder den Zugriff darauf threadsicher machen. Im günstigsten Fall vielleicht sogar einfach nix tun und so drauf zugreifen.