15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


CDaoWorkspace::Close() Access Violation

rmurawka -- rmurawka@ns1.aic.fr
Wednesday, February 19, 1997

Environment : VC++4.1, Win95


Problem :

The worker thread and the interface thread use the same database and=20
recordsets.

At the end of the program(SDI application) , the following error occurs=20
in CDaoWorkspace::Close()
when we call m_pDAOWorkspace->Release:
Unhandled exception in prog.exe (MFCD404.DLL): 0x00000005: Access=20
Violation
=20

If we stop the worker thread without stopping the interface thread, this=20
error doesn't occur.
But,if we stop the interface thread, this error occurs.

Questions :

Can we use the same CDaoObjects in multithreading ?
Why does this following error occur ?

This is the implementation sample :

The worker thread is implemented in CMainframe Classe.

// Global variables

CCriticalSection synchro;
int     fin_appli;

// this is the threadparams stucture which contained 2 recordsets
// used by interface thread and worker thread.
typedef struct tagTHREADPARMS {
        CTableSet* pTable;
        COrdreTKSet* pOrdre;
} THREADPARMS;

...
...
...
...

// We stop the worker thread in CMainFrame destructor
CMainFrame::~CMainFrame()
{
        HANDLE  hThread;


        if (fin_appli)
        {
        hThread =3D pThread->m_hThread;
        fin_appli=3D0;
        WaitForSingleObject(hThread,INFINITE);
        }
}

...
...
...

// this is the worker thread.

UINT fonctionthread(LPVOID param)
{
        ...
        ....
        ....

        THREADPARMS*    m_pparms;

        m_pparms=3D(THREADPARMS*)param;
        m_pThreadOrdreTKSet=3Dm_pparms->pOrdre;
        m_pThreadTableSet=3Dm_pparms->pTable;

        m_pThreadOrdreTKSet->Open();
        m_pThreadTableSet->Open();

        fin_appli=3D1;

        while(fin_appli)
        {
                synchro.Lock();

                m_pThreadOrdreTKSet->Addnew();
                m_pThreadTableSet->Addnew();

                ...
                        ...
                        ...
                m_pThreadOrdreTKSet->Update();
                m_pThreadTableSet->Update();

                synchro.Unlock();

        }
       =20
        m_pThreadOrdreTKSet->Close();

        m_pThreadTableSet->Close();

        m_pThreadOrdreTKSet =3D NULL;
        m_pThreadTableSet =3D NULL;


        return 0;
}


//
// We execute the worker thread in Mainframe.cpp
//
void CMainFrame::OnConnexion()
{
        CFrameWnd* pFrameWnd;
        THREADPARMS s_pt;

        // TODO: Add your command handler code here

        if (!fin_appli)
        {
                pFrameWnd =3D (CFrameWnd*)AfxGetMainWnd();

                CStillSaxbyDoc* m_pDoc =3D (CStillSaxbyDoc*=20
)pFrameWnd->GetActiveDocument( );

                s_pt.pTable =3D &m_pDoc->m_tableSet;
                s_pt.pOrdre =3D &m_pDoc->m_ordretkSet;

                pThread =3D AfxBeginThread(fonctionthread,&s_pt);
        }


        CLoginDlg Login;
        Login.DoModal();
       =20
}
thank you for your help.
--
**********************************
*        Richard MURAWKA         *
**********************************
* 86 place de la R=E9publique      *
* 01400 Chatillon sur Chalaronne *
* France                         *
* E-Mail : rmurawka@aic.fr       *
**********************************



dgraham@xypoint.com
Thursday, February 20, 1997

There is a Knowledge Base article on this that may help you.  It's been
a while since I took care of my similar problem but I am certain that it
had to do with replacing the DAO DLL's.

HTH

>----------
>From: 	rmurawka[SMTP:rmurawka@ns1.aic.fr]
>Sent: 	Wednesday, February 19, 1997 1:48 PM
>To: 	mfc-l@netcom.com
>Cc: 	mfc-l@netcom.com
>Subject: 	CDaoWorkspace::Close() Access Violation
>
>Environment : VC++4.1, Win95
>
>
>Problem :
>
>The worker thread and the interface thread use the same database and 
>recordsets.
>
>At the end of the program(SDI application) , the following error occurs
>
>in CDaoWorkspace::Close()
>when we call m_pDAOWorkspace->Release:
>Unhandled exception in prog.exe (MFCD404.DLL): 0x00000005: Access 
>Violation
> 
>
>If we stop the worker thread without stopping the interface thread,
>this 
>error doesn't occur.
>But,if we stop the interface thread, this error occurs.
>
>Questions :
>
>Can we use the same CDaoObjects in multithreading ?
>Why does this following error occur ?
>
>This is the implementation sample :
>
>The worker thread is implemented in CMainframe Classe.
>
>// Global variables
>
>CCriticalSection synchro;
>int     fin_appli;
>
>// this is the threadparams stucture which contained 2 recordsets
>// used by interface thread and worker thread.
>typedef struct tagTHREADPARMS {
>        CTableSet* pTable;
>        COrdreTKSet* pOrdre;
>} THREADPARMS;
>
>...
>...
>...
>...
>
>// We stop the worker thread in CMainFrame destructor
>CMainFrame::~CMainFrame()
>{
>        HANDLE  hThread;
>
>
>        if (fin_appli)
>        {
>        hThread = pThread->m_hThread;
>        fin_appli=0;
>        WaitForSingleObject(hThread,INFINITE);
>        }
>}
>
>...
>...
>...
>
>// this is the worker thread.
>
>UINT fonctionthread(LPVOID param)
>{
>        ...
>        ....
>        ....
>
>        THREADPARMS*    m_pparms;
>
>        m_pparms=(THREADPARMS*)param;
>        m_pThreadOrdreTKSet=m_pparms->pOrdre;
>        m_pThreadTableSet=m_pparms->pTable;
>
>        m_pThreadOrdreTKSet->Open();
>        m_pThreadTableSet->Open();
>
>        fin_appli=1;
>
>        while(fin_appli)
>        {
>                synchro.Lock();
>
>                m_pThreadOrdreTKSet->Addnew();
>                m_pThreadTableSet->Addnew();
>
>                ...
>                        ...
>                        ...
>                m_pThreadOrdreTKSet->Update();
>                m_pThreadTableSet->Update();
>
>                synchro.Unlock();
>
>        }
>        
>        m_pThreadOrdreTKSet->Close();
>
>        m_pThreadTableSet->Close();
>
>        m_pThreadOrdreTKSet = NULL;
>        m_pThreadTableSet = NULL;
>
>
>        return 0;
>}
>
>
>//
>// We execute the worker thread in Mainframe.cpp
>//
>void CMainFrame::OnConnexion()
>{
>        CFrameWnd* pFrameWnd;
>        THREADPARMS s_pt;
>
>        // TODO: Add your command handler code here
>
>        if (!fin_appli)
>        {
>                pFrameWnd = (CFrameWnd*)AfxGetMainWnd();
>
>                CStillSaxbyDoc* m_pDoc = (CStillSaxbyDoc* 
>)pFrameWnd->GetActiveDocument( );
>
>                s_pt.pTable = &m_pDoc->m_tableSet;
>                s_pt.pOrdre = &m_pDoc->m_ordretkSet;
>
>                pThread = AfxBeginThread(fonctionthread,&s_pt);
>        }
>
>
>        CLoginDlg Login;
>        Login.DoModal();
>        
>}
>thank you for your help.
>--
>**********************************
>*        Richard MURAWKA         *
>**********************************
>* 86 place de la Republique      *
>* 01400 Chatillon sur Chalaronne *
>* France                         *
>* E-Mail : rmurawka@aic.fr       *
>**********************************
>



Mike Blaszczak -- mikeblas@nwlink.com
Friday, February 21, 1997

At 22:48 2/19/97 +0100, you wrote:
>Environment : VC++4.1, Win95

>Questions :
>Can we use the same CDaoObjects in multithreading ?

No. It says so in the documentation.  You didn't read
the manual, and that's why you're crashing.


.B ekiM
http://www.nwlink.com/~mikeblas/
These words are my own. I do not speak on behalf of Microsoft.
           This performance was not lip-synched.




Mark -- MHORD@cerner.com
Monday, February 24, 1997

I had a similar problem when I attempted to create a single instance of
my database declared as something like this:

namespace DatabaseStuff {

class myDBase {
private:
	CDAOSomeTable	m_Table1;
  	CDAONutherTable	m_Table2;
	myDBase()	{}	// we only want one so make it accesible only thru a
friend
public:
	friend myDBase &theDBase();

	PopulateSomething(CEdit &box);
	// other stuff....
};



myDBase &theDBase()	{  // in the global namespace so it can be accessed
by everybody

	static myDBase oneDBase;
	return( oneDBase );
}
}
//////////////////// then, in the program I can do this kind of stuff:

using DatabaseStuff::theDBase;

SomeClass::SomeMember()
{
	theDBase().PopulateSomething( m_MyEditWnd );
}
-----------------
Now, when the app exits, it does all the cleanup for the database file
and then when myDBase destructor gets called for the static var
oneDBase, I get the error.

Anyhow, its just a gotcha that I know I should have read in the
documentation but I am used to using this technique for limiting the
number of objects that are created which means I have to use a different
method for the database than I use for other things.

Mark;
CPP_Programmer::J_Mark_Hord() {	mhord@cerner.com;
&Cerner_Corporation =         	http://www.cerner.com;
2800_Rock_Creek_Pkwy;
Kansas_City->MO_64117-2551 = 	(816)472-1024 x2384; }


>-----Original Message-----
>From:	Mike Blaszczak [SMTP:mikeblas@nwlink.com]
>Sent:	Friday, February 21, 1997 11:26 PM
>To:	mfc-l@netcom.com
>Subject:	Re: CDaoWorkspace::Close() Access Violation
>
>At 22:48 2/19/97 +0100, you wrote:
>>Environment : VC++4.1, Win95
>
>>Questions :
>>Can we use the same CDaoObjects in multithreading ?
>
>No. It says so in the documentation.  You didn't read
>the manual, and that's why you're crashing.
>
>
>.B ekiM
>http://www.nwlink.com/~mikeblas/
>These words are my own. I do not speak on behalf of Microsoft.
>           This performance was not lip-synched.
>



Richard Morris -- richard@softwaremachine.com
Tuesday, February 25, 1997

I have seen this problem too in VC++ 4.1 and 4.2.

I suspect there are some rough edges in the MFC code that are related to
CWinThread, COle and CDAO, and thread management.

I reduced my code to just a few lines which would cause the access violation.
I found the it could be caused by starting a thread having nothing to do
with COle or CDAO in CMyApp::InitInstance (which in the minimum case to
cause the access violation, did nothing but
start and then go to sleep waiting for an event telling it to terminate
itself, no DAO, no OLE, nothing
else) and then opening and closing a CDaoDatabase.  Then stopping and
cleaning up the thread in CMyApp::ExitInstance.  Then when the COle code
does the deinitialization in CWinApp::ExitInstance the 0xc0000005 access
violation occurrs.

I used the debugger and explored the MFC code trying to find the connection
to the access violation without much success.  Also searched the Knowledge base
without results.  But with a little deduction and experimentation, I found
that I could move starting the  thread to CMainFrame and the problem was
solved.  This lead me to the my initial suspicion.

I find it quite curious as in my app where I ran into this problem, I have
several other threads doing
different tasks without any problems, but with this one case of starting the
thread in CMyApp::Initinstance, it seems there is a gotcha waiting to bite,
with this very specific set of events.

Has any one else run into this?  What are your thoughts?

*******************
At 12:46 PM 2/24/97 -0600, you wrote:


****************************************************************
Live now.
Make now always the most precious time.
Now will never come again.
	 - Captain Jean-Luc Picard, U.S.S. Enterprise





Become an MFC-L member | Вернуться в корень Архива |