Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / Managed C++ / November 2006

Tip: Looking for answers? Try searching our database.

How to fire async events and c++/clr

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
BartMan - 06 Nov 2006 21:38 GMT
Greetings,

I am trying to fire aysnc events in c++/clr, and I can't seem to get it to
work.
It seems to work fine in c#, but when I try c++/clr, I can't seem to get it
to compile in the c++/clr class.

I.) Event Testing in C#, which works fine:
public class CSharpEventTest
   {
       public event CSharpDelegate AsyncEvent = null;
       public event CSharpDelegate SyncEvent = null;

       public void FireAsyncEvent(string message)
       {
           if (AsyncEvent == null) return;
           
           AsyncEvent.BeginInvoke(message, null, this);
       }

       public void FireSyncEvent(string message)
       {
           if (SyncEvent == null) return;

           SyncEvent(message);
       }

   }

II. Event Testing in MC++, which doesn't compile correctly.
public delegate bool MCDelegate(System::String^ errorCode);

public ref class MCEventTesting
{
public:
   MCEventTesting(void);

   event MCDelegate^ EventSync;
   event MCDelegate^ EventASync;

public:
void FireEventAsync(System::String^ errorCode)
{                           
// Doesn't compile, gives an error:
//"invalid argument for delegate constructor; delegate target needs to be a
// pointer to a member function"
MyErrorDelegate^ delg = gcnew MyErrorDelegate(EventASync(errorCode));
delg.BeginInvoke(NULL, delg);
}

// Works fine
void FireEventSync(System::String^ errorCode)
{
  EventSync(errorCode);
}
};

Thanks for any suggestions!
Tamas Demjen - 06 Nov 2006 23:00 GMT
> public:
> void FireEventAsync(System::String^ errorCode)
[quoted text clipped - 3 lines]
> // pointer to a member function"
> MyErrorDelegate^ delg = gcnew MyErrorDelegate(EventASync(errorCode));

MyErrorDelegate^ delg = gcnew MyErrorDelegate(this,
   &MCEventTesting::EventASync);

The first argument (this) is a handle to the handler class. The second
argument (&MCEventTesting::EventASync) is a pointer to the handler function.

Tom
BartMan - 07 Nov 2006 14:25 GMT
Hello Tamas,

Thanks for the reply.  I tried your recommendation for the method.
> MyErrorDelegate^ delg = gcnew MyErrorDelegate(this,
>     &MCEventTesting::EventASync);

But I get the following error:
Error 1 error C3364: invalid argument for delegate constructor; delegate
target needs to be a pointer to a member function

For some reason the "event MCDelegate^ EventASync;" is not working as a
member function.

Any ideas?

> > public:
> > void FireEventAsync(System::String^ errorCode)
[quoted text clipped - 11 lines]
>
> Tom
Tamas Demjen - 07 Nov 2006 17:31 GMT
> But I get the following error:
> Error 1 error C3364: invalid argument for delegate constructor; delegate
> target needs to be a pointer to a member function

You didn't disclose the declaration of MyErrorDelegate, but it looks
like it's not compatible with the handler. Your event handler must have
the exact same arguments and return type as the delegate. For example,
MCDelegate is declared

public delegate bool MCDelegate(System::String^ errorCode);

So the event handler must be declared

bool xxx(System::String^ errorCode);

Tom
BartMan - 07 Nov 2006 18:53 GMT
> You didn't disclose the declaration of MyErrorDelegate, but it looks
> like it's not compatible with the handler. Your event handler must have
> the exact same arguments and return type as the delegate. For example,
> MCDelegate is declared

Opps a typo on my part the delegate was declared, and the event is declared
below, and it has the same values, so I don't understand how it cannot
compile.
Especially since the c# works fine?

// Here is the Delegate:
public delegate bool MCDelegate(System::String^ errorCode);

public ref class MCEventTesting
{
public:
MCEventTesting(void);

event MCDelegate^ SyncEvent;
event MCDelegate^ AsyncEvent;  // Async Event?????

public:
// Fire the event as an async event.
void fireErrorEventAsync(System::String^ errorCode)
{                               
// ERROR: "Complains that it must be a pointer to a member function."
MCDelegate^ delg = gcnew MCDelegate(this,&MCEventTesting::AsyncEvent);
AsyncEvent->BeginInvoke("test",nullptr,this);       

// Also tried this, it didn't work complained that it needs to be a data
member.   
// MCEventTesting::AsyncEvent->BeginInvoke(errorCode,nullptr,nullptr);
}

// Works fine.
void fireSyncEvent(System::String^ errorCode)
{
    SyncEvent(errorCode);   
}
};
Ben Voigt - 07 Nov 2006 20:01 GMT
>> You didn't disclose the declaration of MyErrorDelegate, but it looks
>> like it's not compatible with the handler. Your event handler must have
[quoted text clipped - 29 lines]
> member.
> // MCEventTesting::AsyncEvent->BeginInvoke(errorCode,nullptr,nullptr);

Use this along with a custom event:

private:
MCDelegate^ AsyncHandlerList;

public:
event MCDelegate^ Async {
 MCDelegate^ add(MCDelegate^ d) { return AsyncHandlerList =
Delegate::Combine(AsyncHandlerList, d); }
 MCDelegate^ remove(MCDelegate^ d) { return AsyncHandlerList =
Delegate::Remove(AsyncHandlerList, d); }
}

void fireErrorEventAsync(System::String^ errorCode)
    MCEventTesting::AsyncHandlerList->BeginInvoke(errorCode,nullptr,nullptr);
}

> // Works fine.
> void fireSyncEvent(System::String^ errorCode)
> {
> SyncEvent(errorCode);
> }
> };
BartMan - 07 Nov 2006 20:19 GMT
> event MCDelegate^ Async {
>   MCDelegate^ add(MCDelegate^ d) { return AsyncHandlerList =
> Delegate::Combine(AsyncHandlerList, d); }
>   MCDelegate^ remove(MCDelegate^ d) { return AsyncHandlerList =
> Delegate::Remove(AsyncHandlerList, d); }
> }
Hello Ben,

Thanks for the reply.  The above mentioned code issues the following error:
Error 1 error C3919: 'Async::add': function must have type 'void (MCDelegate
^)'

I tried changing it to "void add(MCDelegate^ d) {....}", but that didn't
seem to work either.
Ben Voigt - 07 Nov 2006 20:23 GMT
>> event MCDelegate^ Async {
>>   MCDelegate^ add(MCDelegate^ d) { return AsyncHandlerList =
[quoted text clipped - 12 lines]
> I tried changing it to "void add(MCDelegate^ d) {....}", but that didn't
> seem to work either.

also take out the word return.  Oh, and the += and -= operators do work in
C++.  Here's a snippet out of my own code:

virtual event System::EventHandler^ Closed

{

void add( System::EventHandler^ handler )

{

CloseHandlers += handler;

}

void remove( System::EventHandler^ handler )

{

CloseHandlers += handler;

}

}
BartMan - 07 Nov 2006 20:33 GMT
> also take out the word return.  Oh, and the += and -= operators do work in
> C++.  Here's a snippet out of my own code:
[quoted text clipped - 20 lines]
>
> }

Thanks that is very good to know.  I did not know that operator support has
been added in c++/clr.  Thank for all your help, it is exactly what I needed.

Here is my final version which seems to execute properly.

public delegate bool MCDelegate(System::String^ errorCode);

public ref class MCEventTesting
{
public:
MCEventTesting(void);

event MCDelegate^ SyncEvent;
                   
private:
MCDelegate^ AsyncHandlerList;

public:
event MCDelegate^ Async
{
   
void add(MCDelegate^ d)
{
            AsyncHandlerList =
(MCDelegate^)System::Delegate::Combine(AsyncHandlerList, d);
}

void remove(MCDelegate^ d)
{
AsyncHandlerList = (MCDelegate^)System::Delegate::Remove(AsyncHandlerList,
d);
}
}

public:
void fireErrorEventAsync(System::String^ errorCode)
{                                                       
MCEventTesting::AsyncHandlerList->BeginInvoke(errorCode,nullptr,nullptr);
}

void fireSyncEvent(System::String^ errorCode)
{
    SyncEvent(errorCode);   
}
};
Ben Voigt - 07 Nov 2006 20:43 GMT
> Thanks that is very good to know.  I did not know that operator support
> has
[quoted text clipped - 23 lines]
> AsyncHandlerList =
> (MCDelegate^)System::Delegate::Combine(AsyncHandlerList, d);
As I showed you with my code, this can be shortened to: AsyncHandlerList +=
d

> }
>
> void remove(MCDelegate^ d)
> {
> AsyncHandlerList = (MCDelegate^)System::Delegate::Remove(AsyncHandlerList,
> d);
And here, AsyncHandlerList -= d

> }
> }
[quoted text clipped - 3 lines]
> {
> MCEventTesting::AsyncHandlerList->BeginInvoke(errorCode,nullptr,nullptr);
Don't forget to get the IAsyncResult and call EndInvoke later.  And yes,
this is a pain, but it's required.  You can pass an anonymous method as the
callback to BeginInvoke to help with this.

> }
>
[quoted text clipped - 3 lines]
> }
> };

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.