| 

.NET C# Java Javascript Exception

3
Hallo,

ich habe ein Programm B, welches von einem anderen Programm A aus aufgerufen wird.
Programm A wartet so lange, bis eine Funktion in Programm B fertig ist.
Programm B ist eine GUI Anwendung, die gestartet wird, wenn von Programm A aus eine Funktion in Programm B aufgerufen wird.
Ich möchte die aufgerufene Funktion in Programm B jetzt solange warten lassen, bis eine bestimmte Schaltfläche gedrückt wurde. Der GUI-Thread in Programm B darf dabei nicht "einfrieren". Kann mir jemand eine Lösung vorschlagen?

Danke
16.07.2012
Ralf1 11 1 2
5 Antworten
1
Da gibt es unzählige Möglichkeiten, welche genommen wird, ist abhängig von dem Ziel was man erreichen will. Schwierig, die richtige Antwort zu geben, weil Du nicht genau beschreibst was Du wirklich erreichen willst.

a. Du stellst das Property Modifiers der Schaltfläche, die gedrückt werden soll, von Private auf Public, und hängst Dich anschließend im Programm A an dieses Event. Ist aber eine etwas unsaubere Methode :-)

b. Du definierst selber ein Event in Programm B und abonnierst diese in Programm A. Wenn Schaltfläche gedrückt wird, feuerst Du das Event und kannst Programm A sogar noch Werte übergeben.
16.07.2012
JEwen 2,7k 5
Ich bin zwar VB.Net'ler, aber mich würde mal interessieren, wie Variante B aussehen könnte.
muffi 16.07.2012
1
Ok, dann versuche ich es mal :-)
Definiere zunächst eine neue Klasse, die Du von EventArgs ableitest. z.B.

public class ButtonDrueckerEventArgs : EventArgs
{
private readonly string myText;
public ButtonDrueckerEventArgs(string _myText)
{
myText = _myText;
}
public string MyText
{
get
{
return myText;
}
}
}


Dann definierst Du in Programm B das Event wie folgt:
public event EventHandler<ButtonDrueckerEventArgs> RaiseButtonDrueckerEvent;


Anschließend, natürlich ebenfalls in B, den passenden Handler implementieren:
public void OnButtonDrueckerEvent(ButtonDrueckerEventArgs e)
{
EventHandler<ButtonDrueckerEventArgs> handler = RaiseButtonDrueckerEvent;
if (handler!=null) // Sicherstellen dass Event auch abonniert wurde!
{
handler(this, e);
}
}

Im OnKlick-Ereignis der gewünschten Schaltfläche rufst Du dann diesen Handler beispielsweise wie folgt auf:
OnButtonDrueckerEvent(new ButtonDrueckerEventArgs("Das wäre mein Text"));


In Programm A erstellst Du ja das Formular (Programm B) ungefähr so
frmProgramB frm = new frmProgrammB();
frm.ButtonDrueckerEvent += MyButtonDrueckerEvent;
frm.Show();
frm.RufemethodeXY();


So, fehlt nur noch
void MyButtonDrueckerEvent(object sender, ButtonDrueckerEventArgs e)
{
Messagebox.Show(e.MyText);
}


So, dies war jetzt ziemlich vereinfacht dargestellt, aus dem Stehgreif. Aber so sollte es funktionieren.
16.07.2012
JEwen 2,7k 5
Hui, das muss ich mir ganz in Ruhe geben... aber: Danke :-)
muffi 16.07.2012
1
Meinst du so etwas?

Programm A:

B.StarteEingaben()
//warten, bis B fertig ist:
While (B.Eingabeunvollständig)
{
System.Threading,Thread.Sleep(1000);
}
18.07.2012
Dominik.Hilke 131 2
B hat eine Property Eingabeunvollständig, die bei StarteEingaben auf false initialisiert wird. Wenn in Programm B die Taste für fertig gedrückt wird, setzt du die Property auf true.
A kann derweil ständig die Property abfragen und erst weiter machen, wenn der Wert auf true geändert wurde.
Das funktioniert aber nur wenn B asynchron gestartet wird. Das Beispiel sollte dazu dienen, besser zu verstehen, was du erreichen willst - Eine Umsetzung über Events wie von JEwen vorgeschlagen ist weitaus eleganter.
Dominik.Hilke 23.07.2012
Es stellen sich jedoch Fragen:
Warum muss A warten?
Warum kann B nicht als Dialog geöffnet werden? (dann wartet A ohnehin, bis der Schließen-Button in B gedrückt wurde)
Was sind A und B (Assemblies, Projekte oder Klassen) wirklich und wie soll die Kommunikation zwischen ihnen stattfinden.
Dominik.Hilke 23.07.2012
0
Hallo,

das verstehe ich so noch nicht. Wie wartet die Funktion RufemethodeXY jetzt darauf, dass eine Taste gedrückt wird?
17.07.2012
Ralf1 11 1 2
1
Sorry, aber irgendwie ist es mir ein Rätsel, was genau Du willst. Mal soll Programm A warten, dann wieder eine Methode, die aufgerufen wird, aber dann warten soll. hm. Aber, was hindert dich daran, in Methode XY ebenfalls das Event ButtonDrueckerEvent zu abonnieren. mach Dir ein globales bool field bButtonGedrueckt, anfangs false und wenn das Event ausgelöst wird, setze dieses im Eventhandler auf true. In der Methode XY wartes Du mit while (!bButtonGedrueckt) { Application.DoEvent; } Oder halt, wenn eh alles in ProgrammB stattfindet, beim drücken der Schaltfläche.
JEwen 17.07.2012
0
Also, das ist gar nicht so schwierig.
Programm A ruft eine Funktion in Programm B auf und wartet solange, bis diese Funktion abgearbeitet ist. Die Funktion in Programm B darf aber erst beendet werden, nachdem in Programm B eine Schaltfläche betätigt wurde.
Programm B darf jedoch nicht einfrieren, wenn es auf das Betätigen einer Taste wartet.
Ich werde deinen Vorschlag mal aufnehmen und es mit einer do while Schleife probieren und in dieser dann mit Application.DoEvents arbeiten...
Ich dachte, das jemand evtl. eine elegantere Lösung kennt.

Danke für deine Antworten
17.07.2012
Ralf1 11 1 2
Bitteschön. Aber wie ruft denn A die Funktion in B auf? Als Thread, asyncron? Oder einfach eine Methode? Wenn nein, geht es ja eh erst nach A zurück, wenn diese Methode verlassen wird. Und für B, geht es dann tatsächlich einfach über die While Schleife. Setze die Abbruchbedingung halt einfach beim drücken der Taste auf True. Das Einfrieren verhinderst Du dann mit Application.DoEvents()
JEwen 17.07.2012
1
Aber bedenke bitte, dass DoEvents() einige Probleme mit sich bringen kann und es unter keinen Umständen ein Allheilmittel ist. Die korrekte Vorgensweise ist immer noch, das Warten in einen eigenen Thread auszulagern.
Siehe auch: http://stackoverflow.com/questions/11352301/how-to-use-doevents-without-being-evil
LunaticShade 17.07.2012

Stelle deine Gui-Frage jetzt!