Asynchronous callbacks in C#

A

Ann Huxtable

Hi,

I want to do two types of async callbacks in C#. One involves spawning a
worker thread, and the other does not invlve threads:

Case 1 (Span new thread)
----------------------------
class Fred {

private MyParams params = null ;

/* ctors and dtor*/
public Fred(){;}
~Fred(){;}

void foo() {
params = getConfig();

/* Spawn worker thread that will
notify me when completed */
asynchWorker(methodToInvoke, params, myCallback);
}

void methodToInvoke(MyParams p, MyCallBack cb){
//Do something ..
}

//How do you implement MyCallback, in C++ we have functors
// and in C we have function pointers. How is it done
// in C# ?
}



Case 2 (same thread)
This allows me to register a callback so that
Barney can act like a facade pattern
-------------------------------------------
class Barney {

private MyCallback myCall = null ;

/* ctors and dtor*/
public Barney(){;}
~Barney(){;}

void registerCallback(MyCallBack cb) {
if (cb != null) myCall = cb ;
return;
}

//How do you implement MyCallback, in C++ we have functors
// and in C we have function pointers. How is it done
// in C# ?
}
 
M

Markus Stoeger

Ann said:
//How do you implement MyCallback, in C++ we have functors
// and in C we have function pointers. How is it done
// in C# ?

look up "delegates", thats C#'s function pointers.

hth,
Max
 
J

Jeff Louie

Ann.... A Delegate in C# is a type safe pointer to some function. You
can then
declare an Event which adds += and -= syntax for the delegate. You can
think of the relationship of an Event to a Delegate as analogous to the
relationship of a Property to a Field.

You can also roll your own callback by declaring an interface INotify
with a
method Notify. In your client implement the INotify interface by
providing a
Notify method and pass a reference (this) of type INotify to the server.
When
the server broadcast it invokes clientRef.Notify.

To show how a Delegate is similar to a C callback here is some C++/cli
code:

// C++ CODE
typedef void (*CALLBACK)();
public class Native {
private:
vector<CALLBACK> vPointers;
public:
void Register(CALLBACK cb){
vPointers.push_back(cb);
}
void Broadcast() {
for (unsigned int i=0; i<vPointers.size(); i++) {
(vPointers)();
}
}
...
}

// C++/cli CODE
public delegate void CallbackDelegate();
public ref class Interop {
public:
void Notify() {
Console::WriteLine("Notify");
}

// MAIN UNIT TEST
Interop^ interop= gcnew Interop();
CallbackDelegate^ cd= nullptr;
GCHandle gch;
try {
cd = gcnew CallbackDelegate(interop,&Interop::Notify);
gch = GCHandle::Alloc(cd);
IntPtr ip = Marshal::GetFunctionPointerForDelegate(cd);
CALLBACK cb2 = static_cast<CALLBACK>(ip.ToPointer());
n.Register(cb2);
n.Broadcast();
...
}
finally {
if (gch.IsAllocated) {
gch.Free();
}
}
// n.Broadcast now invalid call

Regards,
Jeff
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top