From: FefeOxy on
Hi,

I have a method which I want to put on a thread because it is a worker
thread. I call the function:

AfxBeginThread(this->backgroundCalc, 0);

where backgroundCalc is a private method in WinForm that is declared:

UINT WinForm::backgroundCalc(LPVOID pParam);


However, I am getting the following error:

error C2665: 'AfxBeginThread' : none of the 2 overloads can convert
parameter 1 from type 'UINT (LPVOID)'

error C3374: managed function 'WinGPIB::WinForm::backgroundCalc'
requires argument list.

Are you not allowed to put methods onto threads? Or are there some
tricks involved? Because if it were not a method, it'd complicate my
code since I'd have to have a delegate of some sort to pass back and
forth the information to and from the form.

From: Ian Semmel on
No, you can't do that, the function has to be static.

You could write a static function and pass the pointer to the WinForm object and
then call a method in it from the thread, but you would have to be aware that
this function is running in the context of the thread and normal thread safety
rules apply.

FefeOxy wrote:
> Hi,
>
> I have a method which I want to put on a thread because it is a worker
> thread. I call the function:
>
> AfxBeginThread(this->backgroundCalc, 0);
>
> where backgroundCalc is a private method in WinForm that is declared:
>
> UINT WinForm::backgroundCalc(LPVOID pParam);
>
>
> However, I am getting the following error:
>
> error C2665: 'AfxBeginThread' : none of the 2 overloads can convert
> parameter 1 from type 'UINT (LPVOID)'
>
> error C3374: managed function 'WinGPIB::WinForm::backgroundCalc'
> requires argument list.
>
> Are you not allowed to put methods onto threads? Or are there some
> tricks involved? Because if it were not a method, it'd complicate my
> code since I'd have to have a delegate of some sort to pass back and
> forth the information to and from the form.
>
From: Tom Serface on
You could derive your class from CWinThread..

class CMyThread : public CWinThread
{
public:
DECLARE_DYNAMIC(COrderQueue)
COrderQueue();
virtual ~COrderQueue();
UINT QueueThread(LPVOID p);
...

}

Then put your calc stuff in the QueueThread routine.

Tom

"FefeOxy" <jacksun007(a)gmail.com> wrote in message
news:1139940583.167826.92260(a)g47g2000cwa.googlegroups.com...
> Hi,
>
> I have a method which I want to put on a thread because it is a worker
> thread. I call the function:
>
> AfxBeginThread(this->backgroundCalc, 0);
>
> where backgroundCalc is a private method in WinForm that is declared:
>
> UINT WinForm::backgroundCalc(LPVOID pParam);
>
>
> However, I am getting the following error:
>
> error C2665: 'AfxBeginThread' : none of the 2 overloads can convert
> parameter 1 from type 'UINT (LPVOID)'
>
> error C3374: managed function 'WinGPIB::WinForm::backgroundCalc'
> requires argument list.
>
> Are you not allowed to put methods onto threads? Or are there some
> tricks involved? Because if it were not a method, it'd complicate my
> code since I'd have to have a delegate of some sort to pass back and
> forth the information to and from the form.
>


From: FefeOxy on
Dear Tom,

I am not sure if I understand what your new class does (what is
DECLARE_DYNAMIC. I read it but was confused).

My backgroundCalc function needs to access several private members such
as GPIBDevice1, 2, and the a static text member in the form (all of
which I've declared within the form). Therefore, using a static member
outside of the function is extremely undesirable. And my project being
of a managed type, I can't use friend to resolve this problem so
basically I'll need to have a bunch of delegates getting info from the
GPIBDevices and updating them in the form, that seems extremely
inefficient and long-winded.

Maybe it's time I re-structure the code.....

From: Scott McPhillips [MVP] on
FefeOxy wrote:
> Dear Tom,
>
> I am not sure if I understand what your new class does (what is
> DECLARE_DYNAMIC. I read it but was confused).
>
> My backgroundCalc function needs to access several private members such
> as GPIBDevice1, 2, and the a static text member in the form (all of
> which I've declared within the form). Therefore, using a static member
> outside of the function is extremely undesirable. And my project being
> of a managed type, I can't use friend to resolve this problem so
> basically I'll need to have a bunch of delegates getting info from the
> GPIBDevices and updating them in the form, that seems extremely
> inefficient and long-winded.
>
> Maybe it's time I re-structure the code.....

You actually have two problems. The first is that the thread function
MUST be a static function. That problem is easy to solve: Pass your
class 'this' pointer as the thread parameter. The static function can
then use the pointer to call a nonstatic function. So with one extra
step you can run your thread code in a member function.

2nd: Your thread will not be able to access your form or its child
controls. With proper synchronization you can safely access your own
variables, but not CWnd functions.

Yes, this can be awkward. It is part of the inherent limitations of
using multithreading.

--
Scott McPhillips [VC++ MVP]