Executing a process with a timeout

S

Steve

I have a bit of "login authentication" code that in the event of a server
error, connection error, etc will take a Looooooong time to timeout. I
wanted to redesign it to call the DAL method in a separate thread (easy
enough) w/ a callback for when it's done. The area I'm having trouble with
is once I determine the timeout period has elapsed, how do I kill the thread
safely?

I asked a threading question here awhile ago and some kind soul pointed me
to Mr' Skeet's great articles. I learned a lot, but apparently not enough
to handle this problem. Jon suggests in his articles that you check a flag
"stopping" to determine if the user has requested the operation be
cancelled, but this requires you to have the opportunity to evaluate the
value of "stopping" - in my case, I make a call to DAL.AuthenticateUser()
and if that method has trouble... well, my execution on the worker thread
sits there waiting for it to return. no chance to check if the timeout
monitor has set "stopping" true or the user has pressed cancel.

I must be thinking about this wrong. As I type this, it seems like my
problem is the main reason people use threads ;0)

I'm trying to do something like this:
User clicks the "Login" button on the form.
Form click event handler calls my AuthMgr.AuthenticateUser(string username)
method
AuthMgr.AuthenticateUser(string username) starts new thread and passes
DAL.AuthenticateUser(string username) as the proc
AuthMgr.AuthenticateUser(string username) starts another thread to monitor
the time elapsed and fire an event (or make a method call) when that happens
at which point I would want to cancel the thread that is servicing the
DAL.AuthenticateUser() method.

problem is, the call to DAL.AuthenticateUser() is hung up on a
DbConnection.Open() call or a DataAdapter.Fill() method and I can't cleanly
kill the thread.



I hope that makes sense to someone out there that has a little time to shed
some light on this problem for me.

Thanks for reading,
Steve
 
M

Mehdi

I have a bit of "login authentication" code that in the event of a server
error, connection error, etc will take a Looooooong time to timeout. I
wanted to redesign it to call the DAL method in a separate thread (easy
enough) w/ a callback for when it's done. The area I'm having trouble with
is once I determine the timeout period has elapsed, how do I kill the thread
safely?

You don't.
I asked a threading question here awhile ago and some kind soul pointed me
to Mr' Skeet's great articles. I learned a lot, but apparently not enough
to handle this problem. Jon suggests in his articles that you check a flag
"stopping" to determine if the user has requested the operation be
cancelled, but this requires you to have the opportunity to evaluate the
value of "stopping" - in my case, I make a call to DAL.AuthenticateUser()
and if that method has trouble... well, my execution on the worker thread
sits there waiting for it to return. no chance to check if the timeout
monitor has set "stopping" true or the user has pressed cancel.

In an ideal world, your DAL would provide a way to start the authentication
process asynchronously with an optional timeout and a way to cancel the
authentication if it takes too long. Obvioulsly, this is not the case and
you have to do with just the synchronous AuthenticateUser() method which
might take ages to execute if the authentication server is unavailable. In
this case, the only solution to make it asynchronous is to do what you've
already done: start a thread and call AuthenticateUser() in this new thread
(using the thread pool wouldn't be a good idea in this case).

Then you want a way to cancel the operation. Quite simply: you can't since
your DAL doesn't provide you with a way to do that. Of course, you could
somehow kill the thread in which AuthenticateUser() executes but that would
be a bad idea since AuthenticateUser() might have acquired resources that
would not be properly released when the thread is killed causing a resource
leak. What you can do though is to simply set a flag when the operation
times out or when the user clicks Cancel. Then, when AuthenticateUser()
returns (or fails), check the flag. If the flags hasn't been set, this
means that the operation hasn't been canceled, so you can invoke the
callback method. If the flag has been set, this means that the operation
has been canceled so do not invoke the callback method and forget about the
results.

This method doesn't actually cancel anything. It simply forgets about the
operation if the user has chosen to cancel it but the operation keeps
running in the background. This is not really a problem if
AuthenticateUser() is just waiting for a dead server to answer. Of course,
there will be a thread running there for nothing until AuthenticateUser()
finally returns but unless the user starts 1000s of authentications per
seconds, this probably won't affect your system's resources or
performances. If AuthenticateUser() does some processor or bandwidth heavy
processing, then forgetting about it and letting it run in the background
will probably be a pretty bad idea but in this case, the only solution to
your problem will be to modify the DAL so that it supports cancelation.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top