简体   繁体   中英

Connecting to an Access database more than once at the same time?

Long version: I want to make an connection to my database, that connection is done asynchronously, because it delays the Form.

Now this is working just fine, but I'm calling the OleDb code to do it's job in a scrollbar_valueChanged event. This is where the problem is caused, because when the users scrolls the scrollbar very fast, the OleDb code in the background also doing stuff.

Now I thought to fix this by just doing 'classname.db.cmd.connection.Close();', and this closes the connection from the background OleDb code, but doesn't prevent the code to try to connect when there is already a connection trying to be made..

Short version: I'm running my 'slow' database reading code with async code, but it's possible to run that same database connection very fast again. And because of how async works ofcourse, it runs the code aside it again and the code tries to connect again, but there still is this other database connection open.

The actual question: So, is there a way to use multiple connection at the same time, reading from the same Access database with OleDb?

First, I am guessing the issue here is the fact that the scroll bar event fires frequently and is using all of the connections available in the connection pool. There are lots of ways around this issue that might help. The first is to add a "Monitor.Enter" on a shared variable before and after you use the connection. The issue this is going to have is it will freeze your UI until the database I/O completes (which is relatively slow). In other words this isn't going to be a satisfactory solution .

Maybe a better way to approach this is as follows (pseudocode):

  • ScrollChange event fires
  • Call an "invalidate screen" or "run database I/O" routine
  • That routine will run only 1 at a time and will load the pending data set(s), whatever those might be.

That DatabaseIO routine could look something like (Pseudocode again):

public void ScrollBarChange(EventArgs e) {
   // to call the routine:
   Thread myThread = new Thread(new ThreadStart(DatabaseIO));
   myThread.Start();

   // any other code you need to run immediately
}

public void DatabaseIO() {
   try {
     Monitor.Enter(this);
     if (ioActive) { pendingEvents = true; return; }
     ioActive = true;
   } finally {
     Monitor.Exit(this);
   }

   // run the database io normally here...

   // check pending events and call "DatabaseIO" again to make sure everything is processed
   if (pendingEvents) {
     pendingEvents = false;
     DatabaseIO();
   }
}

Remember that since this will be run in a thread you won't be able to access UI controls which means you need to save those variables before you start the thread and make sure they don't change during the life of a thread. Otherwise, this is sort of a generically good async pattern for responding to rapidly fired screen events. Hopefully it helps, best of luck!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM