Solved

MDI doc/view and threads.

Posted on 2001-08-11
8
409 Views
Last Modified: 2013-11-20
Once I create a CWinThread derived class, what do i need to add to this in order for the new thread to manage a doc/view/frame created in the MDI parent? I need a thread to be created for each instance of my doc/view/frame.
0
Comment
Question by:deadice
  • 5
  • 3
8 Comments
 
LVL 49

Expert Comment

by:DanRollins
ID: 6378153
There is usually no need to derive from CWinThread.  Just start the thread when you create the view.  But note that there are many pitfalls to multithreading and there are often many ways to avoid using it.

Do you want to see sample code of how to start a thread, and pass it, say, a pointer to a CView-derived class?

What is the reason that you want to have a new thread fro each MDI view?

-- Dan
0
 

Author Comment

by:deadice
ID: 6378188
Sample code would be fine. The app rips/encode mp3's and has a bulit-in tag editor. The tag editor doc/view and the mp3 rip/enc doc/view both need their own thread, since operations can take quite a while and I would like to specify a higher priority for the rip/enc view. I don't see a need for a document in either case, but I've been told this is the way to go.
0
 
LVL 49

Accepted Solution

by:
DanRollins earned 200 total points
ID: 6378455
Here is some very useful code for starting a thread that is associated with a class.  It avoids this big headache:
you can't pass a member fn address to AfxStartThread,  so you are normally stuck with using static member fns which can access only static member variables.  No good if you intend to make multiple instances of this class/thread.

Sample usage in next post


//------------------------ the Mp3Process.h file
class CMp3Process  
{
public:
    CMp3Process();
    virtual ~CMp3Process();
    BOOL    m_fStop;
    UINT    DoThreadProc();

    static  BOOL StartProcessing( void ); // must be static

    //--------------- add your stuff here
    CString sFileInput, sFileOutput
    int nPctDone;
};

//------------------------ the Mp3Process.cpp file
#include "Mp3Process.h"

CMp3Process::CMp3Process()
{
    m_fStop=     FALSE;
    sFileOutput= "c:\\temp\\TempFile.mp3";
    nPctDone=    0;
}
CMp3Process::~CMp3Process()
{
}

//------ used in AfxStartThread; runs the class member proc
//
static UINT Mp3ProcessThreadProc( LPVOID pParam )
{
    CMp3Process* pThis= (CMp3Process*)pParam;
    UINT nRet= pThis->DoThreadProc();
    return( nRet );
}

BOOL CMp3Process::Create( LPCSTR szFile )
{
    m_sFileOutput= szFile;
    //--------------------------------------------- Thread start
    AfxBeginThread( Mp3ProcessThreadProc, this );
}


UINT CMp3Process::DoThreadProc()
{
    while( !m_fStop ) {
        // do some stuff
        // set m_fStop to kill it
    }
    return 0;
}

continued...
0
Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

 
LVL 49

Expert Comment

by:DanRollins
ID: 6378472
Oops, I knew I'd make at least one mistake there.  The Create fn (in the cpp file) should be named StartProcessing

Anyway, to use this class, you must use a two-step sequence:  Instantiate the object, then call the StartProcessing member.

//-----------------
in your View .h

CMp3Process* m_pMp3Process;

in your View .cpp when you want to start processing a file:

m_pMp3Process= new CMp3Process();
m_pMp3Process->StartProcessing( "c:\\temp\\Mettalica.mp3" );

=-=-=-=-=-=-=-
Some notes: In the thread, you will be tempted to do things like call functions in the view to update status text, etc.  This can fail in various ways.  What I have found works best is to give the processing object member variables such as
  int nPctDone;
and
  CString sCurStatus;

Then in the view, run a timer every 1/4 or 1/2 second that simply examines these variables and does whatever UI updating is needed.

-- Dan

0
 
LVL 49

Expert Comment

by:DanRollins
ID: 6378487
Again, I blew it.  The StartProcessing fn must not be static.  In the .h file use:

   BOOL StartProcessing( void );

You will also want to have an EndProcessing() fn.  For best results, EndProcessing() should wait until the thread proc exits (I add an m_fRunning member to the class):

UINT CMp3Process::DoThreadProc()
{
   m_fRunning= TRUE;
   while( !m_fStop ) {
      // do some stuff
   }
   m_fRunning= FALSE;
   return 0;
}

//---------- called from the view (main app thread)
UINT CMp3Process::EndProcessing()
{
   m_fStop= TRUE;
   while ( m_fRunning ) {
       Sleep( 50 );
       // TBD: add a sanity check so doesn't say here forever      
   }
}

-- Dan
0
 

Author Comment

by:deadice
ID: 6378568
Ok. I thought a worker thread would be the solution. The struct of the view is sooo complex, an addition class is quite a good idea, anyways :) I'm gonna try it out tonight. Bloodshot eyes at work again tommorrow!!
0
 
LVL 49

Expert Comment

by:DanRollins
ID: 6382747
Hi, deadice,

Thanks for accepting my comment as an answer.

As an expert here at EE, I am striving to obtain a "4.0" grade point average.  You have awarded me a "B" which degrades my average.  I'm sure that you intended no harm, but I would appreciate it if you would answer a few questions, to help me attain my goal:

1) Was my comment unclear?  Is my use of the English language inadequate?

2) What could I have added that would bring my comment up from a "B" to an "A" ?

3) Are you aware that a comment is not necessarily intended as a "final answer" and that it is possible for you to reply -- asking for clarification and/or followup?

4) Do you understand that Experts must post "general" comments initially -- with the expectation that a followup post by the asker will narrow the focus?  Otherwise, the  expert spends hours writing and testing pieces of code that are not useful to the asker.

5) Did I offend you in any way?

Thanks!
0
 

Author Comment

by:deadice
ID: 6384671
Just a slip. The answer was Excellent. Lemme know how I can change it. I'll pay more attention to the accept anser as comment section. Sorry.
0

Featured Post

Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Host to IP 7 78
how to monitor remote shell execution on linux 9 102
substring method in java 1 124
wordmultiple challenge 12 136
This is to be the first in a series of articles demonstrating the development of a complete windows based application using the MFC classes.  I’ll try to keep each article focused on one (or a couple) of the tasks that one may meet.   Introductio…
Introduction: Dynamic window placements and drawing on a form, simple usage of windows registry as a storage place for information. Continuing from the first article about sudoku.  There we have designed the application and put a lot of user int…
This Micro Tutorial will give you a basic overview how to record your screen with Microsoft Expression Encoder. This program is still free and open for the public to download. This will be demonstrated using Microsoft Expression Encoder 4.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.

831 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question