views:

498

answers:

1

I ran into the problem that two drives connected at nearly the same time can't be processed. I've actually fixed the old scsi way of getting the drive model but I have a feeling I'm about to run into this same problem.

It appears that if a task is executing, such as the one I have checking if the drive is a particular device and unfortunately takes a bit of time if the device has just been connected. That further WM_DEVICECHANGE messages issued while that is executing aren't taken in at all.

Even if I have to store the message and queue it to be handled I'm not sure how I would go about enabling the application to do that while another task is executing. My first guess is I'd have to work with threads?

I have a WM_DEVICECHANGE handler that listens for device arrival and device removal. It gets and returns a drive letter and passes that along to code that adds the drive to a combo box, then checks if it's a psp or just a removable drive, and then has a message dialog asking the user if they want to select this drive or not.

I also have a feeling that the message dialog would prevent WM_DEVICECHANGE messages from processing but until I write the new methods I can't test for it.

Anyway, I thought maybe someone could understand what I mean and point me in the correct direction. I am worried worried that trying to use threads would cause their own little batch of problems?

+2  A: 

I'd not use threads for this. Just take the answers you were given to your other questions, and create a more general solution from that.

If you stay with the one GUI thread you will not miss messages - you will just process them with a little delay. What you may not do however is to ignore further messages while you are processing one and call Application.ProcessMessages() or have a timer involved - this is what you are running into at the moment.

While a modal dialog is active you have a secondary message loop running, and new WM_DEVICECHANGE messages could be received while you are handling a previous one. What I would do to handle this:

  1. Create a list of outstanding drive request records in your application, that record could for example contain the drive letter, all necessary additional data, and a time value for the request to expire.

  2. Upon receiving a WM_DEVICECHANGE message you add a new request record to your list, with the drive letter set up and the timeout value set to current time plus maybe thirty seconds. Every drive letter should be only once in the list. Bonus points for removing requests when a drive is removed again immediately. You need also to enable your timer.

  3. In the timer event handler you first disable the timer, then you execute your code to process the request. If it succeeds you remove the request from the list. If it does not succeed, but the current time is past the timeout request, then you remove the request from the list, alerting the user that there was a problem. If there is still time left until the timeout you keep the request in the list, to be retried the next time. Finally you re-enable the timer, but only if the list of requests is not empty.

Using such a method you will be able to process as many concurrent requests as your request list can hold entries. There's no need to use threads for that. Using threads would of course improve the responsiveness of the application, but whether you want to burden yourself with the added complexity is for you to decide. There are a lot of threading-related questions on StackOverflow already, browse them to get a feeling for what new problems you will be dealing with.

mghie
I will look at ahwt yiu say, unfortunately im dropping the wmi method entirely i know know how to fix the old scsi passthrough code which is much faster. My problem is i step through the debugger and i see the wmdevicechange fire for F:\ but it does not fire for I:\ even though both are connected.
Brian Holloway
@Brian: If you do indeed only receive one WM_DEVICECHANGE message then using threads would probably not make a difference, anyway. You can of course also enumerate all the drives and determine which drives are new or no longer there.
mghie