DAO 'multithread' - interesting problem
David Ohlssen -- DAVIDO@COMMERCE.CTECH.AC.ZA Tuesday, May 14, 1996 NT 4.0.1234 VC++4.0 I know DAO is not multithread re-entrant. (Yet? Ever?) I have a worker thread that mans the comms port and has to write records to disk as they come in. The user app has to display some of that data, perhaps older records, but according to user request. I have made a second worker thread that has sole control over the DAO db recordsets. Both the comms thread and the CView supply and retrieve data by asking the db thread via the pointers. The communication is via flag-pointers and data in the CWinApp class, located via AfxGetApp(). The db thread opens the database and closes it when there is a signal from exitinstance. Exit instance waits for the threads to signal completion then calls the default. There are judicius Sleep calls in every waiting situation. When exitinstance calls the default there is an access violation. I have traced and found that it calls AfxDaoTerm() which crashes in the call to RemoveAll() workspaces. The actual crash is because of m_pBlocks containing zero and being used as a pointer in MFC code. Is this because the db thread opened the database and we are letting CWinApp clean up (the main app thread)? It can't be, because the pointer to AfxDaoTerm is set for the main thread otherwise it wouldnt be called. I NEED the separate db thread, to provide rapid service to the comms thread regardless of user activity such as listbox fill. I have tried using the CDaoDatabase class on the stack and heap and in the app. I have tried a 5 second sleep before calling the default ExitInstance(). Even with no daorecordsets being opened it crashes. If I comment out the CDaoDatabase::Open and Close lines, it does not crash. A non-thread version of a similar program works fine with similar DAO structure, except that the database variables are in the CDocument and the close is triggered by CView::DestroyWindow(). The worker control functions are normal global functions (not classes), inside the app source file for convenience. David O. Ohlssen I _____________________________________ I I | Davido@Commerce.CTech.ac.ZA | I I | __ ____________ | I I | / \/ Cape Town \ _ | I I |__/ South Africa \/ \__________| I I_________________________________________I
MCVICAR DAVID ugrad -- com50008@paisley.ac.uk Thursday, May 16, 1996 [Mini-digest: 2 responses] David Ohlssen wrote: > > NT 4.0.1234 VC++4.0 > > I have tried using the CDaoDatabase class on the stack and heap and > in the app. I have tried a 5 second sleep before calling the > default ExitInstance(). Even with no daorecordsets being opened it > crashes. If I comment out the CDaoDatabase::Open and Close lines, > it does not crash. A non-thread version of a similar program works > fine with similar DAO structure, except that the database variables > are in the CDocument and the close is triggered by > CView::DestroyWindow(). I experienced similar problems when doing something similar in a console based Win32 based server. I traced through the MFC code and found that unless there was a CWinApp available that there was an exception. This was due to DAO trying to call the App to get a pointer to a function to shutdown the Jet engine. By adding an unused CWinApp class I solved this. It is possible that with the multiple threads accessing DAO that once one of the threads is killed that it shuts down the Jet database engine, when you then try to access it again you would get the exception you talk of. This is only a suggestion and mayt be wrong but this definitely happened in a console based app. Possibly this is one for the FAQ ? -- David A. McVicar EMail: dmcvicar@bcs.org.uk / com50008@paisley.ac.uk Phone - Home : 01505 322099 - Anytime before 22:00 Mobile: 0973 386463 - Anytime -----From: Dan KirbyHi, DAO can only be used in the primary thread of an application. This information comes straight from the DAO developers. You must remember that DAO is a technology which comes from the VB/Access products which support applications with a single primary thread. That is the only way by which DAO has been tested. Some folks have been able to get things to work if they use the dbDAO C++ classes from the DAO SDK and don't intialize OLE in any other thread except the thread which uses DAO but, again, it really was never tested with that in mind. The DAO team is looking at making DAO at least apartment model in the future but there have been no timeframes announced for this. One key problem is that DAO uses the Jet engine and that is not thread-safe so the DAO group probably won't do much until the underlying db engine changes to allow thread safety. The MFC problem you are seeing is because MFC performs a DAO call from the primary thread to Release the DBEngine object but the object was created in a different thread. To do this, an OLE object must follow OLE apartment threading rules which DAO does not. --dan
Brian Jones -- BrianJ@ats-nt.apptechsys.com Monday, May 20, 1996 Is CDatabase an effective workaround for this problem? ---------- From: owner-mfc-l[SMTP:owner-mfc-l@netcom.com] Sent: Thursday, May 16, 1996 5:44 PM To: mfc-l Subject: Re: DAO "multithread" - interesting problem [Mini-digest: 2 responses] David Ohlssen wrote: > > NT 4.0.1234 VC++4.0 > > I have tried using the CDaoDatabase class on the stack and heap and > in the app. I have tried a 5 second sleep before calling the > default ExitInstance(). Even with no daorecordsets being opened it > crashes. If I comment out the CDaoDatabase::Open and Close lines, > it does not crash. A non-thread version of a similar program works > fine with similar DAO structure, except that the database variables > are in the CDocument and the close is triggered by > CView::DestroyWindow(). I experienced similar problems when doing something similar in a console based Win32 based server. I traced through the MFC code and found that unless there was a CWinApp available that there was an exception. This was due to DAO trying to call the App to get a pointer to a function to shutdown the Jet engine. By adding an unused CWinApp class I solved this. It is possible that with the multiple threads accessing DAO that once one of the threads is killed that it shuts down the Jet database engine, when you then try to access it again you would get the exception you talk of. This is only a suggestion and mayt be wrong but this definitely happened in a console based app. Possibly this is one for the FAQ ? -- David A. McVicar EMail: dmcvicar@bcs.org.uk / com50008@paisley.ac.uk Phone - Home : 01505 322099 - Anytime before 22:00 Mobile: 0973 386463 - Anytime -----From: Dan KirbyHi, DAO can only be used in the primary thread of an application. This information comes straight from the DAO developers. You must remember that DAO is a technology which comes from the VB/Access products which support applications with a single primary thread. That is the only way by which DAO has been tested. Some folks have been able to get things to work if they use the dbDAO C++ classes from the DAO SDK and don't intialize OLE in any other thread except the thread which uses DAO but, again, it really was never tested with that in mind. The DAO team is looking at making DAO at least apartment model in the future but there have been no timeframes announced for this. One key problem is that DAO uses the Jet engine and that is not thread-safe so the DAO group probably won't do much until the underlying db engine changes to allow thread safety. The MFC problem you are seeing is because MFC performs a DAO call from the primary thread to Release the DBEngine object but the object was created in a different thread. To do this, an OLE object must follow OLE apartment threading rules which DAO does not. --dan
| Вернуться в корень Архива |