Click to See Complete Forum and Search --> : Problem with BeginInvoke


lloydy
July 29th, 2004, 05:38 PM
Hi,

I am using a BeginInvoke call, which is moving to the correct thread, and calling the correct function, but is not passing the arguments!

My code when calling BeginInvoke is:


DataSetArgs* Args = new DataSetArgs(sender, DSN);

//Update the Config

if(System::Windows::Forms::Control::InvokeRequired)
{
Object* pList[] = {this, dynamic_cast<System::EventArgs *>(Args)};

Type* DelegateType = __typeof(System::Windows::Forms::Form);

System::EventHandler *thisEventHandler =
new System::EventHandler(this, &Form1::AutoConfig);

System::Windows::Forms::Control::BeginInvoke(thisEventHandler, pList);

}else
{
AutoConfig(this, EArgs);
}



The function called is:

public: void AutoConfig(Object* sender, System::EventArgs* Args){
//Problem, at this points, args is empty
}



Can anyone see why this is not being passed?

Thanks in advance

lloydy
July 30th, 2004, 12:08 AM
I have solved my own problem. For those with a similar problem, here is an example of "a" solution:

Firstly create a delegate

public: __delegate void AutoConfigDelegate(Object *sender);


Then to trigger

public: System::Void DataSetUpdate(Object *sender)
{
if(System::Windows::Forms::Control::InvokeRequired)
{
//Create the delegate.
AutoConfigDelegate* dlgt =
new AutoConfigDelegate(this, &Form1::AutoConfig);

Object* pList[] = {sender};

IAsyncResult* MarshalResult =
System::Windows::Forms::Control::BeginInvoke(dlgt, pList);

System::Windows::Forms::Control::EndInvoke(MarshalResult);
}else
{
AutoConfig(sender);
}


This will call the following function

public: void AutoConfig(Object* sender)
{
//stuff
}


Take note that you can only use the call System::Windows::Forms::Control::BeginInvoke with a Windows Form. This is because the ISynchronizeInvoke interface is already impemented. To do this from another type you will have to implement the ISynchronizeInvoke interface.

I found a very good article regarding this at
http://www.fawcette.com/vsm/2003%5F02/magazine/columns/qa/ (http://)

It is very helpful :thumb: When invoking from another class, implement a ISynchronizeInvoke interface and then call


//Create delegate(be careful of scope)
public: __delegate void NotifyDelegate(ArrayList* msg);


//Trigger
dlgtNotify = new NotifyDelegate(this, &SerialHandler::Notify);
Object* pList[] = {msg};
m_Synchronizer = new Synchronizer(); //Synchronizer is implementation of ISynchronizeInvoke interface
m_Synchronizer->BeginInvoke(dlgtNotify, pList);


This would trigger the following fn

public:void Notify(ArrayList* msg){
//stuff
}


See ya :wave: