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

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


opening a DaoRecordSet while in (worker-)threads...

Jan Van Overbeke -- jan.vo@kortleven.tornado.be
Friday, November 15, 1996


Environment: VC++ 4.0 (Educ), Win 95

I'm writing a FidoNet Point System.

Importing messages from FidoNet is a busy process, so I put it in a worker-thread (AfxBeginThread()). The thread does its job beautifully. But after the thread has finished, my app does an illegal operation as soon as I access the database again:

IAGO caused an invalid page fault in
module DAO3032.DLL at 0137:0470408b.

I'm sure it is caused by CMyDaoRecordSet::Open(), and that the constructor is harmless.

Documentation mentions something about TLS (Thread Local Storage), which means static vars are not shared across threads. But I haven't found any samples on this subject.

Anyone putting me in the right direction?


UINT DoIt(LPVOID pParam)
{
    CMyDaoRecordSet set;
        // Next line is the cause of all trouble
        // After this thread has finished,
        // doing set.Open() while in CMyApp-thread is illegal
        // Exiting the app isn't healthy either
    set.Open();
    return 0;
}

class CMyDialog : public CDialog
{

    ...
    void CMyDialog::OnButton1()
    {
        AfxBeginThread(DoIt, this, THREAD_PRIORITY_ABOVE_NORMAL);
    }
    ...

}



 |[oo][oo]| Jan Van Overbeke, IAGO development
 |[==] >03|   jan.vo@tornado.be 2:292/600.9  2:292/517.11
 |O*0000*O|  http://www.tornado.be/~jan.vo/ (iago/)

... "We need change and we need it fast
     Before rock's just part of the past
     Cause lately it all sounds the same to me" ... Ramones



Steve Mark -- steve@otms.com
Monday, November 18, 1996

[Mini-digest: 3 responses]

All DAO database access must occur in a single thread, from creating the
workspace to destructing the workspace.  If you are not explicitly creating
a workspace, one is being created for you when you do the database open.
To fix this, explicitly create and open a workspace in the thread, then
pass this as an argument to the CDaoDatabase class contructor.  When you
are all done with database access, close the database and the workspace, in
the thread.  Make sure that these closings happen whenever the thread is
terminated, including at app termination.

Steve
_________________________________________
Steven Mark
Principal Consultant, On-The-Mark Systems
Tel: 510.648.9514       Fax: 510/648/9507
steve@otms.com        http://www.otms.com
-----From: "Michael Potter" 

 DAO is not thread-safe. You should use DAO only in the primary thread of
an application.

Mike Potter

-----From: browkl@inel.gov (Kenneth L Brown)

If you look in the documentation in the Programming with MFC:
Encyclopedia, under the topic DAO and MFC, there you will find the
following caution:

"Caution   DAO is not supported on Win32s. Further, DAO 3.x is not
thread-safe. You should use DAO only in the primary thread of an
application."

I can't say for sure but this may be your problem.  There may be updates
for DAO that fix this.  Maybe someone else knows of such a fix. 
Comments?

Kenneth Brown
browkl@inel.gov



pjn -- pjn@indigo.ie
Tuesday, November 19, 1996

[Moderator's note: Sorry about the multiple messages last night.
My modem connection dropped while I was sending a batch of
messages, and I had to resend.]

[Mini-digest: 2 responses]

On 15 nov 96 19:54:04 PST, you wrote:

>
>Environment: VC++ 4.0 (Educ), Win 95
>
>I'm writing a FidoNet Point System.
>
>Importing messages from FidoNet is a busy process, so I put it in a =
worker-thread (AfxBeginThread()). The thread does its job beautifully. =
But after the thread has finished, my app does an illegal operation as =
soon as I access the database again:
>
>IAGO caused an invalid page fault in
>module DAO3032.DLL at 0137:0470408b.
>
>I'm sure it is caused by CMyDaoRecordSet::Open(), and that the =
constructor is harmless.
>
>Documentation mentions something about TLS (Thread Local Storage), which=
 means static vars are not shared across threads. But I haven't found any=
 samples on this subject.
>
>Anyone putting me in the right direction?
>
>
>UINT DoIt(LPVOID pParam)
>{
>    CMyDaoRecordSet set;
>        // Next line is the cause of all trouble
>        // After this thread has finished,
>        // doing set.Open() while in CMyApp-thread is illegal
>        // Exiting the app isn't healthy either
>    set.Open();
>    return 0;
>}
>
>class CMyDialog : public CDialog
>{
>
>    ...
>    void CMyDialog::OnButton1()
>    {
>        AfxBeginThread(DoIt, this, THREAD_PRIORITY_ABOVE_NORMAL);
>    }
>    ...
>
>}
>
>
>
> |[oo][oo]| Jan Van Overbeke, IAGO development
> |[=3D=3D] >03|   jan.vo@tornado.be 2:292/600.9  2:292/517.11
> |O*0000*O|  http://www.tornado.be/~jan.vo/ (iago/)
>
>... "We need change and we need it fast
>     Before rock's just part of the past
>     Cause lately it all sounds the same to me" ... Ramones
>


Simple answer to this is that DAO is not thread safe. It can only be
used from the main thread of your application. If you really must do
this in a thread then currently you must use ODBC.


                             '''	  =20
                             @ @
+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
ooO-(_)-Ooo=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+
|                                           PJ Naughter              |
|                                                                    |
| Software Developer                   Email: pjn@indigo.ie          |
| Softech Telecom                      Tel:   +353-1-2958384         |
|                                      Fax:   +353-1-2956290         |
| Author of DTime - A Collection       URL:   http://indigo.ie/~pjn  |
| of Date & Time classes for MFC                                     |
|                                                                    |
|                  Addr: 7 Woodford, Brewery Road, Stillorgan,       |
|                        Blackrock, Co. Dublin, Republic of Ireland  |
+=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+
-----From: Mike Blaszczak 

At , Jan Van Overbeke wrote:

>Environment: VC++ 4.0 (Educ), Win 95

>Importing messages from FidoNet is a busy process, so I put it
>in a worker-thread (AfxBeginThread()). The thread does its job
>beautifully. But after the thread has finished, my app does an
>illegal operation as soon as I access the database again:

You can't use DAO from multiple threads, period.  You can only
use DAO objects in your application's primary thread-- that is,
you can only use them in the thread in your application which
called OleInitialize().

This is well documented.  See Books Online or the KB.





.B ekiM
http://www.nwlink.com/~mikeblas/
I'm afraid I've become some sort of speed freak.
These words are my own. I do not speak on behalf of Microsoft.





| Вернуться в корень Архива |