Hi, ich versuche mich gerade an einem kleinen "progrämmchen" und möchte hier in einer while-schleife warten, bis ein timerRead_tick ausgeführt wurde. mein Problem ist, dass sobald ich in die while-schleife komme, der timer-read_tick nicht mehr aufgerufen wird (obwohl die Zeit bereits abelaufen ist). Ich dachte dass ein timer_tick wie ein interrupt immer aufgerufen wird, also dass die Schleife für die Abarbeitung des ticks unterbrochen wird, das ist aber nicht so! Wie stelle ich soetwas an? Um es zu konkretisieren: ich muss in meinem Programm auf eine Eingabe warten und in dem Timer_read_tick prüfe ich die Schnittstelle, ob die Eingabe bereits gemacht ist!
ich glaube kaum das jemand ohne ein stücken Quellcode etwas sinnvolles dazu sagen kann ausser - hast du "volatil" beachtet?
die Frage ist vielmehr: wie muss ich einen timer_tick deklarieren dass er auch aufgerufen wird, wenn das Prgoramm (anderweitig) in einer while-Schleife steckt. im Moment verlässt das programm die while nicht, der breakpoint im timer wird nicht angesprungen.
Ist der Timer enabled? Welchen Timer benutzt du überhaupt? Quellcode wäre sehr hilfreich.
Ja sorry, hier der code:
1 | private void tmrRead_Tick(object sender, EventArgs e) |
2 | {
|
3 | ISprogMsg MyMsg; |
4 | ISResult Res; |
5 | |
6 | do
|
7 | {
|
8 | Res = ISprog.Read(ActiveHardware, out MyMsg); |
9 | |
10 | if (Res == ISResult.ERR_OK) |
11 | ProcessMessage(MyMsg); |
12 | } while (!Convert.ToBoolean(Res & ISResult.ERR_QRCVEMPTY)); |
13 | }
|
ich habe ganz oben bei der "do" einen breakpoint, hier kommt das Programm auch wie erwartet hin, sobald ich aber in einer anderen Funktion in der while-Schleife bin, komme ich oben nicht mehr zum Breakpoint. In der ProcessMessage ist die Abbruchbedingung für die while-Schleife - soweit komme ich ja aber nicht
Timer_tick lässt auf System.Windows.Forms.Timer schliessen, läuft das ganze denn innerhalb einer WinForms Anwendung? Der Winforms-Timer braucht nämlich die Message Loop um zu laufen. (s. Beispiel auf http://msdn.microsoft.com/en-us/library/system.windows.forms.timer.aspx) Außerdem ist der Timer Single-Threaded und nicht reentrant, d.h. solange du dich in der do-while Schleife befindest wird das Tick-Event kein 2. Mal ausgelöst. Und, wenn Du mit deiner anderen while-Schleife den GUI-Thread lahmlegst wird da auch kein Tick-Event gefeuert. Gruß, Sascha
Als Beispiel dazu nochmal dieser Schnipsel:
1 | namespace ConsoleApplication1 |
2 | {
|
3 | using System; |
4 | using System.Threading; |
5 | using System.Windows.Forms; |
6 | |
7 | using Timer = System.Windows.Forms.Timer; |
8 | |
9 | public class Program |
10 | {
|
11 | public static void Main(string[] args) |
12 | {
|
13 | Timer tmr = new Timer { Interval = 500 }; |
14 | tmr.Tick += tmr_Tick; |
15 | tmr.Start(); |
16 | |
17 | do
|
18 | {
|
19 | Application.DoEvents(); |
20 | }
|
21 | while (Console.ReadKey().Key != ConsoleKey.Q); |
22 | |
23 | }
|
24 | |
25 | static void tmr_Tick(object sender, EventArgs e) |
26 | {
|
27 | Console.WriteLine("Timer Tick!"); |
28 | |
29 | int counter = 0; |
30 | |
31 | do
|
32 | {
|
33 | counter++; |
34 | Console.WriteLine("Counter erhöht: {0}", counter); |
35 | |
36 | Thread.Sleep(100); |
37 | }
|
38 | while (counter < 50); |
39 | }
|
40 | }
|
41 | }
|
Obwohl der Timer alle 500ms ticken sollte passiert hier nur was ("Timer Tick!"), wenn die Schleife vollständig durchlaufen worden ist. Nimmst Du das Application.DoEvents(); aus der 2. Schleife raus, dann passiert genau gar nichts.
Wobei "Application.DoEvents()" mit Vorsicht zu genießen ist. Dein Programm befindet sich dann in einem nicht mehr definierten Zustand, da du nicht weiß, wie viele Events dann bearbeitet werden und ob du vielleicht sogar in einer anderen Schleife hängen bleibst. Stichwort "Deadlock"
Deshalb hatte ich extra nochmal nachgefragt, was Ihm denn nun geholfen hatte. Application.DoEvents() ist nicht grade die sauberste Art und Weise für Nebenläufigkeit in einer GUI-Applikation. Ich gehe aber davon aus, dass "Ich" nicht mehr antworten wird.
Naja, ist ja leider meistens so. Wenn man sein Problem gelöst hat, meldet man sich nicht wieder. Problem ist ja gelöst. Und Andere haben das Problem bestimmt nicht. -.-
doch genau ICH habe das selbe Problem und möchte es nicht "unschön" lösen Ich probiers nun einfach mal hier, sonst mache ich evtl. ein neuen Thread auf Sascha H. schrieb: > do > { > Application.DoEvents(); > } > while (Console.ReadKey().Key != ConsoleKey.Q); Bei mir sollten nicht alle Events die in dieser Zeit auf tauchen ausgeführt werden. Dies könnte unter Umständen eine längere Zeit sein als gewünscht. Habe mich selber mal auf die Suche durchs www gemacht und dies wird wohl meine auserkorene Lösung sein:
1 | DateTime start = DateTime.Now; |
2 | Thread.Sleep(2000); |
3 | DateTime end = DateTime.Now; |
4 | |
5 | Response.Write("Start: " + start + " |
6 | "); |
7 | Response.Write("Ende: " + end + " |
8 | "); |
9 | Response.Write("Dauer: " + end.Subtract(start).TotalSeconds); |
bluppdidupp schrieb: > Einfach nen Thread nehmen ;D einfach?! vielleicht wenn nichts zurück gegeben wird Sonst muss man sich wieder um die sync. kümmern
Klar, aber je nachdem wie das Problem tatsächlich aussieht kann das unter Umständen sehr einfach sein.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.