Asynchroner Aufruf von Delegates
-
Jochen Kalmbach schrieb:
Du rufst es damit nicht _asynchron_ auf, sondern _synchron_!
In der MSDN-Dokumentation steht eindeutig, dass BeginInvoke
ein Delegaten asynchron für den Thread ausführt , in dem das dem Steuerelement zugrunde liegende Handle erstellt wurde:http://msdn.microsoft.com/de-de/library/system.windows.forms.control.begininvoke(VS.80).aspx
Darüber hinaus habe ich das Beispiel auf die Asynchronität getestet. Funktioniert wirklich.
-
simon.gysi schrieb:
@martin_pavel:
http://msdn.microsoft.com/en-us/library/2e08f6yc.aspxDanke für den Link. Dieses Beispiel ist aber für Microsoft Visual Studio 2008/.NET Framework 3.5. Momentan arbeite ich mit MVS2005/.NET Framework 2.0.
-
simon.gysi schrieb:
Hast Du's schon probiert?
Zeige mal deine Versuche...
SimonDu wolltest meine Versuche haben. Das ist ein davon:
public delegate void ControlValueChangedDelegate (double value); public ref class MyControl : public System::Windows::Forms::UserControl { private: double m_ValueCur; public: ControlValueChangedDelegate^ EvEditWheelValueChanged; private: void SetValueInControl () { //this->EvEditWheelValueChanged (m_ValueCur); // benachrichtigen, dass der Wert geändert wurde if (this->EvEditWheelValueChanged != nullptr) { for each (ControlValueChangedDelegate^ del in this->EvEditWheelValueChanged->GetInvocationList()) System::IAsyncResult^ result = this->BeginInvoke (del, m_ValueCur); // hier muss man sich noch um den Aufruf von EndInvoke() kümmern !!! } } }
Ich habe echt keine Ahnung, wie man hier ein AsyncCallback Delegate aufrufen kann. Die Funktion Control::BeginInvoke hat die folgende Überladungsliste:
Control.BeginInvoke (Delegate)
Control.BeginInvoke (Delegate, Object[])
-
Ich verstehe dein Problem nicht. Es ist exakt die gleiche Weise wie bei C#.
Wo hängst Du genau fest?
Beim instantieren des AsyncCallback's?
-
simon.gysi schrieb:
Ich verstehe dein Problem nicht. Es ist exakt die gleiche Weise wie bei C#.
Wo hängst Du genau fest?
Beim instantieren des AsyncCallback's?Du hast die Nadel auf den Kopf getroffen. Wo und Wie wird eine Instanz von AsyncCallback angelegt? In C# passiert das im Delegate. In C++ System::Delegate hat keine BeginInvoke Methode.
-
#include "stdafx.h" using namespace System; using namespace System::Threading; public delegate void AsyncMethodCaller(); public ref class A { public: void func() { Console::WriteLine(L">>> A::func() called; Thread ID " + Thread::CurrentThread->ManagedThreadId); } void endfunc(IAsyncResult^ ar) { AsyncMethodCaller^ d = safe_cast<AsyncMethodCaller^>(ar->AsyncState); d->EndInvoke(ar); Console::WriteLine(L">>> A::endfunc() called; Thread ID " + Thread::CurrentThread->ManagedThreadId); } }; int main(array<System::String ^> ^args) { Console::WriteLine(L">>> main(..) called; Thread ID " + Thread::CurrentThread->ManagedThreadId); A^ a = gcnew A(); AsyncMethodCaller^ d = gcnew AsyncMethodCaller(a, &A::func); d->BeginInvoke(gcnew AsyncCallback(a, &A::endfunc), d); Console::ReadKey(); return 0; }
BeginInvoke(..) und EndInvoke(..) erscheint nicht in der IntelliSense Auswahl... :-))
Simon
-
simon.gysi schrieb:
#include "stdafx.h" using namespace System; using namespace System::Threading; public delegate void AsyncMethodCaller(); public ref class A { public: void func() { Console::WriteLine(L">>> A::func() called; Thread ID " + Thread::CurrentThread->ManagedThreadId); } void endfunc(IAsyncResult^ ar) { AsyncMethodCaller^ d = safe_cast<AsyncMethodCaller^>(ar->AsyncState); d->EndInvoke(ar); Console::WriteLine(L">>> A::endfunc() called; Thread ID " + Thread::CurrentThread->ManagedThreadId); } }; int main(array<System::String ^> ^args) { Console::WriteLine(L">>> main(..) called; Thread ID " + Thread::CurrentThread->ManagedThreadId); A^ a = gcnew A(); AsyncMethodCaller^ d = gcnew AsyncMethodCaller(a, &A::func); d->BeginInvoke(gcnew AsyncCallback(a, &A::endfunc), d); Console::ReadKey(); return 0; }
BeginInvoke(..) und EndInvoke(..) erscheint nicht in der IntelliSense Auswahl... :-))
SimonDas habe ich gerade auch erfahren.Die beiden Methoden erscheinen soger in der MSDN-Hilfe nicht. Das ist ja echt blöd!
Dafür gibt es aber noch bessere Vorgehensweise, und zwar mit BackgroundWorker!
-
So einfach geht das nicht... um irgendwas wieder "synchron" zu machen, muss man jemanden haben, der dies macht (siehe: ISynchronizeInvoke)! Das gibt es im .NET Framework nur bei "Windows-Forms" (Control) und im WPF-Umfeld (SynchronizationContext).
Einfach "so" etwas versuchen wollen zu "synchronisieren", was gar nicht vorhanden ist, geht halt nicht...
-
Jochen Kalmbach schrieb:
So einfach geht das nicht... um irgendwas wieder "synchron" zu machen, muss man jemanden haben, der dies macht (siehe: ISynchronizeInvoke)! Das gibt es im .NET Framework nur bei "Windows-Forms" (Control) und im WPF-Umfeld (SynchronizationContext).
Einfach "so" etwas versuchen wollen zu "synchronisieren", was gar nicht vorhanden ist, geht halt nicht...
Verstehe deine Aufregung nicht.
-
Verstehe mich gerade auch nicht