Timeout STA object from worker thread
Posted on 2005-05-13
This issue has been driving me nuts for a very long time - thus, I'm willing to give a ton of points to whomever helps me get this solved correctly... I tried to give more than 500, but this site won't let me. However, if someone has an idea how to get around that limitation that works, I'm willing to give 1500 - 2000 points if I get a working answer, in a very timely manner. Anyway, on to the problem...
I have an object that is connecting to a middle tier (at the very base it is a SQL Server farm, but that is very much abstracted at this level of interaction). Now, the problem is the performance is horrible & sporadic. For instance, sometimes it will be fully connected in under 1.5 seconds, other times it can take up to 4 or 5 minutes. The problem is that users are constantly opening bugs/raising support issues because of these long connection times - so I need to give hte users the ability to cancel the connection if it starts taking too long.
My proposed solution:
1) Start timer (delay 2 seconds first in case it connect quickly - give it a chance first, so to speak)
2) Attempt to connect
In the timer callback, which after the initial 2 seconds will fire every 1 second do:
1) If not your first time, skip to step 3.
2) Pop up a progress dialog that has a cancel button
3) Increment the progress dialog with the current amount of timet aking to connect (+1 on the progress UI tick)
Within the progress dialog:
1) if user does nothing, just continue being updated by the timer that is running - no big deal
2) If a user hits 'Cancel' to cancel the connection b/c it is taking too long, we need to cancel the connection on the main thread --> this is the problem!!
Obviously, throwing an exception in that case will not work since it will be happening in a child thread - the exception will never make it back to the main thread since they are not in the same stack.
1) The object that is doing the connection is from the OM exposed/created for this middle tier system. It is STA and completely non-thread safe. Therefore, I cannot create the connection in a worker thread and then pass it back to the main thread - it will throw exxceptions and bring down the sytstem when you try to use it. I have no control over that object's implementation and therefore have no way of having it updated to be thread safe.
2) The object connecting also does not expose anyway to set a predeterimined amount fo time before timing out (like a normal SQL server connection attempt allows you to do). Again, I have no control over this - I must use it the wya it is.
3) The connection object will eventually timeout on its own from the middle tier & return an exception to me, but it is undeterministic - sometimes within 30 seconds, sometimes it can take up to 10 mintues or more - a very bad user experience since it makes the entire app look hung.
Does anyone have an idea of how to fix this? How can I make a way for my users to cancel this operation. I am doing this all in C#. Thanks ahead of time for trying to help!