We help IT Professionals succeed at work.

We've partnered with Certified Experts, Carl Webster and Richard Faulkner, to bring you a podcast all about Citrix Workspace, moving to the cloud, and analytics & intelligence. Episode 2 coming soon!Listen Now

x

Using AfxBeginThread

has
has asked
on
Medium Priority
467 Views
Last Modified: 2013-11-20
I have A dialog Box Application;

with push of calculate button my calculation should start but
dialog box should be responsive during calculation takes place.

my way is not a good way but is:

header file  contains->

private:
  static UINT calc(LPVOID pParam);
 void calculate();
 anyusefulclass any; // may be any class used in calculation

so on,

cpp file contains ->

void MyDlg::OnButtonCalc()
{
   AfxBeginThread(Calc,this);   // i know, should not use pointer
}

UINT MyDlg::Calc(LPVOID pParam)
{
  MyDlg* this_dlg;
  this_dlg = (MyDlg*) pParam;
  this_dlg->calculate();
  return 0;
}

void  MyDlg::calculate()
{
  a = 5 + 8; // simple calculation
 any.doit(); // calculation involving declared any object
}



now this workes under release version. but debug version
gives assertion error, on line 856 of wincore.cpp saying i
should not pass c++ objects. if i do not use any.doit() in
my calculation function, both debug and release works fine.

however, i need a better way. I tried to pass m_hWnd (as suggested in wincore.cpp) and ->

void MyDlg::OnButtonCalc()
{
   AfxBeginThread(Calc,m_hWnd);   // i know, should not use pointer
}

UINT MyDlg::Calc(LPVOID pParam)
{
  MyDlg* this_dlg;
  HWND hWnd;
  hWnd =pParam;
 //this_dlg->Attach(hWnd);
  this_dlg = (MyDlg*) Cwnd::FromHandle(hWnd);
  this_dlg = (MyDlg*) pParam;
  this_dlg->calculate();
  return 0;
}

itried this with and without attach, did not work, what is the best way to activate a member function on a separate thread, thanks
Comment
Watch Question

Commented:
The 2nd method will never work, since MyDlg is your class and hWnd is only one of its member variable, you not expect to restore a class simply from such a window handle.

However, your first approach seems to be fine, except that CalC should not be declared as a member function (and you need not it to be one).  You must remember that a C++ function takes one more parameter (this) than it seems to need in prototype.  However AfxBeginThread() will not take care of this.

So simply try to declare CalC as a separate function (does not belong to any class) and see how.

Hope this helps.
has

Author

Commented:
yes I know that, if it is a separate function it will work for sure,
if it is global, it will work, but my point is to assign a member function
to a separate thread ! so please i need answers on this direction

Commented:
I can't answer since the question is locked... try this:

create through the class wizard a new class that inherits from CWinThread.
inplement it's InitInstanc to do your calc. ( the calc. func. can be a member variable of the threads class, passed in it's constroctor  ).

return from the initInstance FALSE that will terminate the thread.
you can wait on the handler of the thread for knowing when it's terminated ( WaitForSingleObject() ).
A code with the same idea is the one of the application's in a dialog based project.
has

Author

Commented:
I will try shaig's comment, seems interesting, thank you both

Commented:
I don't understand why you want this function to be a member of a class.  Even if it is, the "this" pointer has to be passed in a different way and therefore lose all the benifit of being a member function.  You see, in your CalC function, you will simply call Calculate() which is a TRUE member function, all the work is done there.  Actually you can define your CalC() function as being static, since it does not access anything of the class, right?  So it really makes no difference whether it belongs to the class or not.
has

Author

Commented:
i have so many objects used im my calculation ( see my declaration)

anyusefulclass any; // may be any class used in calculation

and

any.doit(); // calculation involving declared any object

see my question. if I do not have this "any" object or if I create it dynamically, then no problem. as it is no way. namely "any" object
ruins it with my first method.
Hi,
From your description, it seems that everything is ok. There is no harm in using static member functions for worker threads. The program should run without any problem like assertions. The only thing that is not clear is what your "anyusefulclass" is doing. What type of class it is and what exactly it's doing in it's "doit()" function. From the assertion that you are getting, one thing is clear that somewhere in your worker thread you are tampering with any of the windows, either the dialog box, it's own child controls or some other window. Since you are getting the assertion only when doit() is called, apparently you are doing the prohibited thing in this function itself. So please verify it again. So make sure there is no window associated with the anyusefulclass. The reason is like this:
Whenever you create a window. MFC stores it's pointer in two maps, one is a permanent map in which pointers to windows created expicitly by user are stored and the other map is a temporary one in which pointers to windows such as dialog controls are stored. These maps are specific to a thread, so your main application will have a set of these maps and if you create another thread then that thread will have it's own map set. The assertion you are getting is exactly due to this problem. Hope this solves your problem.

Not the solution you were looking for? Getting a personalized solution is easy.

Ask the Experts
has

Author

Commented:
yes i have carried the main dialog pointer to that anyuseful
class object to manipulate some edit boxes. thanks
Access more of Experts Exchange with a free account
Thanks for using Experts Exchange.

Create a free account to continue.

Limited access with a free account allows you to:

  • View three pieces of content (articles, solutions, posts, and videos)
  • Ask the experts questions (counted toward content limit)
  • Customize your dashboard and profile

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.