ThreadPool and GUI awaiting question

I am new to threads and need help. I have a data entry application that takes an exorbitant amount of time to insert a new record (i.e. after 50-75 seconds). So my solution was to send an insert statement through the ThreadPool and let the user start entering data for a record during this insert, which returns a new record ID while that insert is running. My problem is that the user can click Save before the new ID is returned from this insert.

I tried to insert a boolean variable that gets true from an event from this thread when it's safe to save. Then I put

while (safeToSave == false)  
{  
    Thread.Sleep(200)  
}  

      

I think this is a bad idea. If I run the save method before this protector comes back, it gets stuck.

So my questions are:

  • Is there a better way to do this?
  • What am I doing wrong here?

Thanks for any help. Doug

Edit for more information:

It does an insert into a very large (approaching maximum) FoxPro database. The file contains about 200 fields and almost the same number of indices on it.
And before you ask, I cannot change the structure of it as it was here before I was, and there is a ton of old code caught in it. The first problem is that in order to get a new id, I have to first find the max (id) in the table and then increment and check it. This takes about 45 seconds. Then the first insert is simple and inserts this new id and input field. This table cannot / cannot be placed in DBC to exclude auto-generating ids etc.

@ joshua.ewer
You have the right move and I think in the short term I'll just disable the save button, but I'll be exploring your idea of ​​passing it to the queue. Do you have any links to MSMQ that I should look out for?

+1


source to share


5 answers


Everyone else, including you, has covered the underlying issues (insert time, why you insert and then update), so I'll stick with just the technical issues with the suggested solution. So, if I understood the flow correctly:

  • Topic 1: Start data entry for recording

  • Topic 2: Background calls to the database to get a new identifier

  • The save button is always on, if the user tries to save before Thread 2 exits, are you putting # 1 to sleep 200ms?



The simplest, not the best answer is to simply disable the button, and this thread will make a callback to the delegate that enables the button. They cannot initiate an update operation until you are sure everything is configured accordingly.

Although, I think a much better solution (although it might be bloated if you are just creating a Q&D front end for FoxPro) would be to queue these save operations. The user can log in as quickly as possible, then the requests are injected into something like MSMQ and they can run asynchronously.

+1


source


1) Many :), for example, you can disable the Save button when the thread inserts the object, or you can set up a Work Thread that handles the queue of "save requests" (but I think the problem here is that the user wants change the newly created entry, so maybe it can be turned off)

2) I think we need some more code to understand ... (or maybe a sync issue, I'm not a fan of threads either)



btw, I just don't understand why the insert should take so long. I think you should check this code first! <- as Charles previously stated (sorry didn't read the post) :)

+2


source


Use a future , not a raw ThreadPool action. Fulfill the future, let the user do whatever they want, when they hit save on the 2nd record, they ask for a value from the future. If the 1st insert is already finished, you will get the ID immediately and the second insert will be allowed. If you are still waiting for the 1st operation, the future will block until it is available and then can do the 2nd operation.

You don't save any time if the user is slower than the operation.

+1


source


First, you should probably figure out and fix the reason the insert is taking so long ... 50-75 seconds is impractical for any modern database to insert a single row and indicates that something else should be addressed. like indexes or locks ...

Second, why are you inserting a record before you have the data? Typically, data-entry applications are encoded so that no insertion is attempted until all the necessary data for insertion has been collected from the user. Are you doing this because you are trying to return a new ID from the database first and then "update" a new empty record with user-entered data later? If so, almost every database provider has a mechanism where you can only insert once without knowing the new ID, and for the database to return a new ID as well ... Which provider database are you using?

0


source


Is such a solution possible:

Pre-compute unique IDs before the user even starts adding. Keep a list of unique IDs that are already in the table but are seat owners. When the user tries to insert, reserve them one of the unique IDs, when the user clicks the save button, they now replace the storage space with their data.

PS: It's hard to confirm this, but be aware of the next concurrency issue with what you suggest (with or without threads): user A starts adding, user B starts adding, user A calculates ID 1234 as the maximum free id, user B calculates ID 1234 as the maximum free identifier. User A inserted ID 1234, User B inserted ID 1234 = Boom!

0


source







All Articles