thread parameters

  • Thread starter Thread starter Mike
  • Start date Start date
M

Mike

I would like to pass an Object* to a delegated thread function.
However, the framework does not accommodate this. I have seen examples
using VB and even C#. In fact, C# appears to have language facilities
that make accomplishing this very easy. However, I only have the
luxury of coding this up in C++. So far the closest I've been able to
come to facilitating this is something like the following.

typedef void (*DelegateFunc)(Object __gc *);

__gc class ThreadClosure
{
private:

static Object* c_pArgs;
static DelegateFunc c_pfDelegate;

public:

ThreadClosure(
DelegateFunc pfDelegate,
Object* pArgs)
{
c_pfDelegate = pfDelegate;
c_pArgs = pArgs;
}

virtual ~ThreadClosure(void) {}

static void Run(void)
{
if (c_pfDelegate)
c_pfDelegate(c_pArgs)
}
};

The one flaw in the above scheme is the use of statis members. I have
no real guarantee between constructing an instance and initializing
the static closure and passing the run execution to the thread
delegate that the closure will remain what I set it to.

Ideally I'd like to pass a closure instance, or the Run method address
from that instance, to the thread delegate. Is this possible in the
C++ implementation of ThreadStart()?

Any tips would be massively appreciated!

Best regards,
Michael Powell
 
Hi Mike,
I would like to pass an Object* to a delegated thread function.
However, the framework does not accommodate this. I have seen examples
using VB and even C#. In fact, C# appears to have language facilities
that make accomplishing this very easy. However, I only have the
luxury of coding this up in C++. So far the closest I've been able to
come to facilitating this is something like the following.

You can use the exact same facilities in MC++ as C# and VB.NET have for
asynchronous invocation of delegates. Here's a simple example:

#using <mscorlib.dll>

using namespace System;
using namespace System::Threading;

public __gc class ClassWithThreads
{
public:
void MethodWithArg(Object* data)
{
Object* argt __gc[] = { __box(Thread::CurrentThread->GetHashCode()),
data};
Console::WriteLine (
S"MethodWithArgs(): Thread Hash={0}, Data={1}", argt
);
}
};

public __delegate void ThreadDelegate(Object*);

int main()
{
Console::WriteLine(S"Main(): Thread Hash={0}",
__box(Thread::CurrentThread->GetHashCode()));
ClassWithThreads* obj = new ClassWithThreads();


ThreadDelegate* del = new ThreadDelegate(obj,
&ClassWithThreads::MethodWithArg);

IAsyncResult* ar = del->BeginInvoke (
S"some string",
0 /* AsyncCallback */,
0 /* asyncState */
);
ar->AsyncWaitHandle->WaitOne();
}
 
(e-mail address removed) (Mike) wrote in message
I figured it out. Something closer to this.

typedef void (*DelegateFunc)(Object __gc *);

__gc class ThreadClosure
{
private:

Object* m_pArgs;
DelegateFunc m_pfDelegate;

public:

ThreadClosure(
DelegateFunc pfDelegate,
Object* pArgs)
{
this->m_pfDelegate = pfDelegate;
this->m_pArgs = pArgs;
}

virtual ~ThreadClosure(void) {}

static void Run(void)
{
// It is up to caller and callee (thread) to agree
// what the arguments mean (if anything).
if (this->m_pfDelegate)
this->m_pfDelegate(this->m_pArgs)
}
};

and to use... (psuedocode)

ThreadClosure* pClosure = new ThreadClosure(...);
// This is the key!
ThreadStart* pDelegate = new ThreadDelegate(
pClosure, ThreadClosure::Run);
Thread* pThread = new Thread(pDelegate);
pThread->Start();

Best regards,
Michael Powell
 
Back
Top