Laden...

schnelles buttonklicken bricht threading.timer ab

Erstellt von Br0t vor 15 Jahren Letzter Beitrag vor 15 Jahren 1.444 Views
B
Br0t Themenstarter:in
1 Beiträge seit 2008
vor 15 Jahren
schnelles buttonklicken bricht threading.timer ab

Hallo zusammen,

ich komme eigentlich aus der Java-Ecke habe damit aber jetzt schon seit zwei Jahren nicht mehr ernsthaft gearbeitet.
Seit zwei Wochen probiere ich mich jetzt erst an C#, für DAU-Fehler entschuldige ich mich daher jetzt schonmal.
So nun zu meinem Problemchen.
Ich habe um mal ein bischen mit dem Arbeitsspeicher zu spielen eine mini Windows Forms Anwedung gebastelt, mit der ich per Klick den Score von Windows Pinball um 1Mio erhöhe.
In textBox1 wird mit Hilfe eines Timers alle 0,2 Sekunden der aktuelle Score ausgegeben. Klicke ich jetzt mehrmals relativ flott auf button1 wird dieser Timer gestoppt bzw textBox1 nicht mehr aktualisiert...
Der Score wird trotzdem weiterhin erhöht.
Woran könnte das liegen?

Gruß und Danke schonmal im Vorraus


		private int ReadMem() {
			IntPtr hWnd = FindWindow(null, "3D-Pinball für Windows - Space Cadet");
			UInt32 pid;
			UInt32 tid = GetWindowThreadProcessId(hWnd, out pid);
			hWnd = OpenProcess(PROCESS_VM_READ, false, pid);
			if((int)pid == 0) {
				return -1;
			}
			uint size = 4;
			uint vNumberOfBytesRead = 0;
			byte[] vBuffer = new byte[size];
			ReadProcessMemory(hWnd, (IntPtr)0xC1AEBA, vBuffer, vBuffer.Length, ref vNumberOfBytesRead);
			return BitConverter.ToInt32(vBuffer, 0);
		}
		private void WriteMem(int i) {
			IntPtr hWnd = FindWindow(null, "3D-Pinball für Windows - Space Cadet");
			UInt32 pid;
			UInt32 tid = GetWindowThreadProcessId(hWnd, out pid);
			hWnd = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, false, pid);
			uint size = 4;
			uint vNumberOfBytesRead = 0;
			byte[] vBuffer = new byte[size];
			vBuffer = BitConverter.GetBytes(i);
			WriteProcessMemory(hWnd, (IntPtr)0xC1AEBA, vBuffer, vBuffer.Length, ref vNumberOfBytesRead);
		}
		private void TimerHandler(object state) {
			int iWert = ReadMem();
			string sMsg;
			if(iWert == 0 && !bProgStatus) {
				button1.Invoke(new MethodInvoker(delegate() { button1.Enabled = true; }));
				bProgStatus = true;
				sMsg = "-";
				textBox3.Invoke(new MethodInvoker(delegate() { textBox3.Text = textBox3.Text+"Programm gestartet\r\n"; }));
			}
			else {
				sMsg = iWert.ToString();
			}
			if(iWert == -1) {
				button1.Invoke(new MethodInvoker(delegate() { button1.Enabled = false; }));
				bProgStatus = false;
				sMsg = "-";
				if(!bMsgsended) {
					textBox3.Invoke(new MethodInvoker(delegate() { textBox3.Text = textBox3.Text + "Pinball starten\r\n"; }));
					bMsgsended = true;
				}
			}
			textBox1.Invoke(new MethodInvoker(delegate() { textBox1.Text = sMsg; }));
		}
		private void StartTimer() {
			TimerCallback handler = new TimerCallback(TimerHandler);
			string state = "...";//sinnlos
			System.Threading.Timer timer = new System.Threading.Timer(handler, state, 0, 200);
		}
        	private void Form1_Load(object sender, EventArgs e){
			textBox3.Text = "Moin moin\r\n------\r\n";
			StartTimer();
		}
		private void button1_Click(object sender, EventArgs e){
			WriteMem(ReadMem() + 1000000);
        }      

915 Beiträge seit 2006
vor 15 Jahren

Hrm, mach mal nen Invoke rein bei WriteMem oder beim button1_Click wo WriteMem aufrufst.

Bei WriteMem brauchst für as Invoke natürlich ein neues delegate:

private delegate void WriteMemDelegate(int i);

Du rufst zwar in der Methode WriteMem keine GUI Elemente auf, aber da dir ja das Handle des Fensters holst und via WriteProcessMemory könnte es dadurch zu Problemen kommen und der Thread vom Timer schmiert irgendwo zwischendrinnen ab, davon bekommst ja so direkt nichts mit, ausser evtl. im "Output" ("Ausgabe" in deutschen VS glaube ich) das der Trhead XY beendet wurde.

Wie vernichtet stand Andreas unter den flammenden Augen seiner Kunden.
Ihm war's, als stünde des Schicksals dunkle Wetterwolke über seinem Haupte X(

5.299 Beiträge seit 2008
vor 15 Jahren

Hi & welcome!

Äh, die zündende Idee zum Prob habich eignt lcih nich - kannes sein, daß häufiges Klicksen einen Fehler im ReadMem erzeugt, im Nebenthread?
Daraufhin verabschiedet sich der Timer, und die Fehlermeldung fliegt ins Nirvana, weil Nebenthread.
Kriegst du auch im Ausgabefenster keine Fehlermeldung?

Also am ReadMem würdich mal herumdebuggen, Debug-Meldungen einbauen, TryCatch dranmachen und so.

Der frühe Apfel fängt den Wurm.