Ich habe jetzt mind. 2 Stunden meine Anwendung ge-debugged und seh den Wald von lauter Bäumen nicht mehr. Also entschuldige ich mich schonmal im Voraus, falls diese Frage zu einfach ist.
Was ich möchte:
Ein Prozess soll 2 Sekunden laufen, pausiert werden und der nächste Prozess soll angeworfen werden, 2 Sekunden laufen, pausiert werden, nächster Prozess, usw.
Ich gehe dabei folgendermaßen vor (dank der Tipps aus einem anderen Beitrag):
- Prozess1 starten (als Thread)
- 2 Sekunden warten
- Prozess1 pausieren
- Wenn Prozess sicher pausiert ist, wird PauseEvent ausgelöst
- im PauseEvent starte ich dann den nächsten Prozess also: Prozess2 starten, 2 Sekunden warten, Prozess2 pausieren. --> PauseEvent wird gefeuert, gleiches Spiel mit Prozess3 usw..
Das Ganze in Code gegossen sieht so aus:
Worker wrk = new Worker();
private void btnStart_Click(object sender, EventArgs e)
{
wrk.PauseEvent += new Worker.PauseEventHandler(wrk_PauseEvent);
wrk.Start();
Thread.Sleep(2000);
wrk.Pause();
}
void wrk_PauseEvent(object sender, EventArgs e)
{
//nächsten thread aufrufen. zu testzwecken und der einfachheit halber rufe ich den selben thread nochmal auf
wrk.Start();
Thread.Sleep(2000);
wrk.Pause();
}
using System;
using System.Threading;
namespace TEST
{
class Worker
{
public delegate void PauseEventHandler(object sender, EventArgs e);
public event PauseEventHandler PauseEvent;
private bool bPause = false;
public void Start()
{
if (bPause)
{
Resume();
}
else
{
Thread tDoIt = new System.Threading.Thread(new System.Threading.ThreadStart(DoIt));
tDoIt.Start();
}
}
private void Resume()
{
bPause = false;
}
public void Pause()
{
bPause = true;
}
private void DoIt()
{
//do something
Thread.Sleep(3000);
CheckForPause();
//do something
Thread.Sleep(2000);
CheckForPause();
}
private void CheckForPause()
{
if (bPause)
{
//event irgendwie asynchron aufrufen?
PauseEvent(this, new EventArgs());
while (bPause)
{
Thread.Sleep(100);
}
}
}
}
}
Jetzt zu meinem Problem:
Wenn das erste Mal pausiert wird, wird richtigerweise das PauseEvent gefeuert aber nachfolgender Code (die while-Schleife zum Warten) nicht ausgeführt.
Kann ich das PauseEvent irgendwie asynchron aufrufen oder ist mein Ansatz komplett falsch gedacht?
Vielen Dank für Eure Unterstützung.
Ich habs jetzt so gemacht, wie von JAck30lena beschrieben.
Von außerhalb der Klasse wird ein Pause-Flag gesetzt. Nach jeder zusammenhängenden Befehlsreihe wird das Pause-Flag geprüft. Wenn true, dann wird der Thread schlafen gelegt und vorher mittels event an die aufrufende Klasse mitgeteilt, dass der Thread nun schläft.
ich habe eine Methode (DoWork) die in einem Thread läuft. DoWork führt viele Befehle hintereinander aus. Bestimmte Befehle gehören aber zusammen und müssen immer komplett ausgeführt werden.
Nun möchte ich den Thread aber pausieren mittels Thread.Suspend.
Wie bekomme ich es hin, dass bestimmte Befehlsfolgen ununterbrechbar sind? Der Thread soll erst schlafen gelegt werden, wenn eine Befehlsreihe (hier 'step') vollständig durchgeführt wurde.
Ich dachte erst, der lock-Befehl würde mir da weiterhelfen aber er scheint in meinem Fall keine Auswirkungen zu haben. Die MessageBox erscheint nicht, nachdem ich den Thread pausiere.
object myLock = new object();
private void DoWork()
{
lock ((myLock)) {
//step1
Delay(3000);
MessageBox.Show("step1 wurde vollständig ausgeführt.");
}
lock ((myLock)) {
//step2
Delay(3000);
MessageBox.Show("step2 wurde vollständig ausgeführt.");
}
lock ((myLock)) {
//step3
Delay(3000);
MessageBox.Show("step3 wurde vollständig ausgeführt.");
}
}
Wie macht man es richtig? Muss ich die Pause-Funktionalität selbst programmieren und dafür sorgen, dass einige Befehlsreihen atomar bleiben? Wie gehe ich da am Besten ran?
ich versuche momentan einen Text direkt in ein Spiel (Vollbildmodus) zu schreiben, um eine Statisktik einzublenden. Das Spiel setzt DirectX voraus und ist nicht von mir.
Meine kläglichen versuche waren folgende:
(Text auf Desktop schreiben)
[DllImport("User32.dll")]
public static extern IntPtr GetDC(IntPtr hwnd);
[DllImport("User32.dll")]
public static extern void ReleaseDC(IntPtr dc);
IntPtr myDC = GetDC(IntPtr.Zero);
Graphics g = Graphics.FromHdc(myDC);
SolidBrush b = new SolidBrush(Color.Red);
g.DrawString("hello world", new Font("Arial", 26), b, new PointF(20, 20));
g.Dispose();
ReleaseDC(myDC);
Damit lässt sich der Text erfolgreich auf den Desktop schreiben. Wenn ich jetzt aber statt IntPtr.Zero, das Handle des Spiels übergebe, passiert leider gar nichts.
Ich vermute fast, dass ich mit diesen mitteln bei Spielen keine Chance habe. Muss ich dafür selbst das DirectX-SDK nutzen oder wie komme ich am Besten zum Ziel?
Original von Kabelsalat
.Net verhällt sich schon richtig: System.UInt32 ist nicht CLS-Konform und daher wird ein System.Int32-Wert erwartet. Beides sind 32bit Werte und sie können daher exakt die selben (Bit-)Werte aufnehmen - der Unterschied liegt nur in der Interpretation eben dieser. Ein DWORD ist nichts anders als ein unsigned int, was dem zu Folge auch bedeutet, dass z.B. -1 auch als UInt32.MaxValue interpretiert wird. Die passenden Integer-Werte erhälst du mittels unchecked((int)4031775092) [natürlich mit entsprechendem Wert].
leider klappts nicht so einfach. Die Zahl passt nicht in eine int-Variable, es muss uint sein.
uint wird nicht von Microsoft.Win32.RegistryValueKind.DWord unterstützt.
Sehr ärgerlich. Gibts ne Möglichkeit die Zahl trotzdem als dword in die Registry zu kriegen? Muss ich es per API-Call erledigen (hoffentlich gehts damit)?
das hab ich mir auch schon gedacht, aber ich schreibe nicht in localmachine. Wenn ich es wollte, würde Windows sicherlich diesen "Das Programm xyz will..."-Dialog bringen.
Man, das nervt echt. Wäre super, wenn jemand ne Lösung für das Problem hat.
edit: Es hilft auch nicht, wenn ich mein Programm als Administrator ausführe, mittels rechte Maustaste aufs Programm-Icons "Als Adminstrator ausführen".
Klar, dass ich da nicht selbst drauf gekommen bin...
Besten Danke, blackcoin.
@Lord Hessia: Dämlicher Kommentar. Du kennst den Zusammenhang doch überhaupt nicht. Außerdem würde ich bestimmt keine Verknüpfung erstellen, wenn ich den Benutzer mit meinem Programm ausloggen möchte...
ich muss diesen Link wieder aus der Versenkung holen.
Der Aspose-Obfuscator funktioniert mit .net 2.0 nicht mehr und Aspose arbeitet nicht mehr an diesem Projekt.
Hat jemand kostenlose alternativen für .net 2.0 C#-Obfuscatoren?
Dadurch wird natürlich der "gedroppte" Text an den bestehenden Text der textBox gehängt.
Ich möchte aber, dass der Text dorthin gedroppt wird, wo sich der Mauszeiger befindet.
Wie kann ich das realisieren?
EDIT: So kann ich den Text dahin droppen, wo sich der Cursor zuletzt befunden hat:
textBox1.SelectedText = e.Data.GetData(DataFormats.Text).ToString();
Ich möchte aber gerne, dass beim Draggen der Cursor in der TextBox sichtbar ist und mit der Maus mitwandert.
ich habe in einem DataGridView eine Spalte mit Comboboxes.
Um eine Combobox aufzuklappen, muss man zweimal auf die Combobox klicken, was mich ziemlich nervt.
Ich denke, dass mit dem ersten Klick die Zeile markiert wird und mit dem zweiten Klick wird erst die Combobox angesprochen (reine Theorie!).
Wie kann ich es bewerkstelligen, dass nur ein Klick notwenig ist, um die Combobox aufzuklappen?