My web service has this code
lock(typeof MyWebServiceClass)
Well i call a 3rd party unchangeable code and it never returns. BOOM! BAM!
I am locked forever now and my web site crashes.
This never returns only happens once in a great while.
Is it possible to create a lock that times out? IE lock the code for 5 minutes then release the lock?
Instead of creating a timed lock, I would limit your third party request by putting it in a separate thread/task. Then, kick off the thread (or task if .NET 4.0 and TPL available to you) and join on the response with a timeout. If the join times out, then cancel the thread (or call the cancel token on the TPL task).
Is it possible to create a lock that times out?
Yes, this unpleasant situation is often refereed to as deadlock.
Usually it is good practice to lock on a static private object instead of locking on instance fields or the class itself:
private static object _syncRoot = new object();
and then:
lock(_syncRoot) {
}
If the 3rd party API has a cancellation mechanism then use that.
lock(typeof MyWebServiceClass)
{
if (ThirdPartyApiThatAcceptsTimeout(TimeSpan.FromMinutes(5)))
{
// The call was successful so proceed.
}
else
{
// The call timed out so bail out.
return;
}
}
However, I highly suspect that this API does not have a cancellation mechanism and so that is why you posed this question. If that is the case then this just got exponentially harder.
The naive approach would be to defer the API call to another thread. If the thread does not respond in a timely fashion then you can abort it.
lock(typeof MyWebServiceClass)
{
var thread = new Thread(
() =>
{
ThirdPartyApiThatCouldBlockIndefinitely();
});
thread.Start();
if (thread.Join(TimeSpan.FromMinutes(5))
{
// The call was successful so proceed.
}
else
{
// The call timed out so bail out.
thread.Abort();
return;
}
}
There are many problems with this though. First, there is no guarantee that the thread will accept the abort request. Since 2.0 there are special rules in the CLR that dictate when aborts can be injected into the thread. I believe the CLR will defer the injection while unmanaged code is executing. So if your API is unmanaged then the abort might not work. Also, aborts are voluntary since the thread could catch ThreadAbortException and ignore it. Second, aborting is dangerous since the abort can be injected asynchronously. This makes it very difficult to guard against corrupting shared state. That is why the AppDomain is normally terminated after an abort.
The safest way to handle this is to put the API call into a separate process. You would have to use interprocess communication protocols like .NET Remoting, WCF, pipes, etc. to transfer data to/from the call which would be a real pain to maintain. But, it would be the safest since you can safely kill the process without the risk of corrupting the AppDomain of the caller.
I really feel for you because this problem is really hard to solve correctly.
Related
I have an automatic betting BOT.
I use a Windows Service and timers to set off a job every 30 seconds in its own thread that takes bets from the DB, loops through and places them.
However in certain occurrences when the job is too long (over 30 seconds) I can get the same bet being placed twice using the same BetPK (unique ID) as the job for placing it runs at the same time as a previously started thread.
I am using C#, NET 4, VS 2012.
At the moment I set a "locked" flag in a table when the job to place bets runs and then unset it on finishing. So if another job runs and the job is locked it will return ASAP. However this is relying on the DB and network traffic.
What would be the best way in C# to prevent a job started by a timer thread from clashing with a previously started thread. I am thinking I could set a flag IN the service controller that spawns the threads so if a job is running another one won't spawn.
However I would like to learn the correct way to handle multi threaed clashes like this. I just lost a couple of hundred pounds today due to 2 LAY bets being placed at exactly the same time. As only one record existed for the Bet, the last bet placed had the Betfair ID updated so I had no clue about the duplicate until I checked Betfairs own page.
I do already do checks to see if the bet has already been placed before trying to place it but in cases where the "placebet" method is running on the same Bet record at exactly the same time then this is no good.
Any help much appreciated.
Thanks
No, the best solution is to keep the locks in the database. The app should be as stateless as possible. You already have a great solution.
Locking inside of your app is error prone and the errors are catastrophic (deadlock, the app stops to work until manually restarted). Locking using the database is much easier, and errors are recoverable.
Just get the locking with the database right. Ask a new question where you post details on what you're doing. I recommend that you XLOCK any betting jobs that you're working on. That way they can only be executed once. Use the power of database locks and transactions to make this work. This is by far easier than app-level threading.
You could always try implementing a db like Redis (redis.io) that offers built in POP functions (http://redis.io/commands/lpop). Redis has a C# client and is super useful for any kind of app where speed is crucial as it keeps the entire db in memory. It's also single threaded which makes it easy to implement distributors for multi-consumer type applications.
I'd also recommend checking out http://kkovacs.eu/cassandra-vs-mongodb-vs-couchdb-vs-redis as it lays out the pros and cons for Redis and other dbs. Might help you make future db decisions.
Old question, I know, but I wanted to throw this out there for anybody that stumbles across it.
C# (and presumably VB.NET) offers a couple of nice options for handling thread synchronization. You can use the lock keyword to block execution until a given lock is available, or Monitor.TryEnter() if you want to specify a timeout (possibly immediately) for taking the lock.
For either of these approaches, you need an object to use for locking. Pretty much any object will do; if you aren't synchronizing access to some object itself (collection, database connection, whatever), you can even just instantiate a throwaway object. For a polling timer, the latter is typical.
First, make sure you have an object to use for synchronization:
public class DatabasePollingClass {
object PollingTimerLock = new object();
...
Now, if you want the polling threads to block indefinitely waiting for their turn, use the lock keyword:
public class DatabasePollingClass {
object PollingTimerLock = new object();
...
protected void PollingTimerCallback() {
lock (PollingTimerLock) {
//Useful stuff here
}
}
}
Only a single thread will be allowed within the lock (PollingTimerLock) block of code at a time. All other threads will wait indefinitely, then resume executing as soon as they can acquire the lock for themselves.
However, you probably don't want that behavior. If you'd rather have the subsequent threads abort immediately (or after a short wait) if another polling thread is still running, you can use Monitor.TryEnter() when taking the lock. This does require slightly more caution, however:
public class DatabasePollingClass {
object PollingTimerLock = new object();
...
protected void PollingTimerCallback() {
if (Monitor.TryEnter(PollingTimerLock)) { //Acquires lock on PollingTimerLock object
try {
//Useful stuff here
} finally {
//Releases lock.
//You MUST do this in a finally block! (See below.)
Monitor.Exit(PollingTimerLock);
}
} else {
Console.WriteLine("Warning: Polling timer overlap. Skipping.");
}
}
}
The additional caution stems from the fact that, unlike the lock keyword, Monitor.TryEnter() requires you to manually release the lock when you're finished with it. In order to guarantee that this happens, you need to wrap your whole critical section in a try block, and release the lock in the finally block. This is to ensure that the lock will be released, even if the polling method fails or returns early. If the method returned without releasing the lock, your program would effectively be hung, as no further threads would be able to acquire the lock.
Another option, which doesn't use locking mechanisms, would be to configure your Timer without a repeat period, i.e. a one-shot Timer. At the end of your polling method, you would dispose the old Timer, and set a new one (you would also need to do this within a finally block to guarantee that the Timer gets reset by the end of the method). This approach would be useful if you want to poll the database at a certain interval since the end of the previous polling. It's a subtle distinction, but it also solves the problem of concurrent polling attempts.
Note that this is a really simple thread concurrency example. As long as all of your locking is happening on threads separate from your UI thread (the message pump itself can become a point of contention), and you're only ever locking a single object, you shouldn't have to worry too much about deadlocks. Those can be really unpleasant to debug; the symptom is usually "application stops responding, and now you get to guess which threads are waiting on what".
Code:
class Controller
{
Some Action Method()
{
...
...
new Thread(() =>
{
//WCF cal- wil execute for around 10 secs.
var result = service.SubmitAndCreateApp(params);
sessionModel.IsAppCreated = result;
}).Start();
return jsonresult;
}
}
Since my WCF call is taking too much time, I don't want to use thread pool and make it starve.
It is evident here that the thread is being created for each client request. How can I optimize this or any other alternative way to achieve this in .Net 4.0 (VS 2010)?
To put it simply: no, don't do this.
That said, you can look at the Task Parallel Library (TPL) in ASP.Net, which can achieve exactly what you are trying to do.
Quick search yielded this posting, which I only glanced over but seems on-point:
http://vizagtechie.blogspot.com/2013/03/parallel-programming-in-aspnet-mvc.html
No. Your server will get DDOS'ed completely. At the very least, request a thread from the thread pool rather than creating your own by hand. If the thread pool runs out, you'll be waiting for one to become available. The rest of the server will continue to be able to work. Of course, your mileage may vary based on many factors.
Each request already gets a thread, so by adding another thread manually, you're creating two threads per request, effectively having your server's ability to field requests. Now, I won't be as apocalyptic as others: on a beefy enough server not fielding thousands of requests per second or more, you'll probably still be okay. It's still bad design, though.
You didn't mention what version of C# you're using on but on 5.0+, you now have async which is how you'd typically handle this situation:
public async Task<ActionResult> SomeActionWithLongRunningProcess()
{
await LongRunningProcess();
return View();
}
This will cause .NET to offload the request, freeing up the thread, until LongRunningProcess() completes.
Your code can complete the call to Some Action Method() and return jsonresult prior to the completion of your WCF call to service.SubmitAndCreateApp(params) (for practical purposes, assume this will happen 100% of the time). If you want that to happen, then your code is fine. If you need the response from the service call in sessionModel.IsAppCreated for your JSON result, however, your code is very broken.
To fix this, you would need to block the action method's thread until the thread it created terminates. This fact along with the fact that the underlying WCF communication channel will already create its own thread to await response from the WCF service call (a synchronous WCF call is really just an async call that blocks until the response is received) makes creating a new thread pointless.
We're working with a 3rd-party legacy system that requires thread affinity for some of the tear-down logic. We're also hosting a WCF service inside IIS which, under heavy loads will do a rude unloading of our app domain. In these cases it falls to the critical finalizer to do cleanup. Unfortunately, without thread affinity in the finalizer, the 3rd-party system deadlocks.
So roughly:
public class FooEnvironment : CriticalFinalizerObject, IDisposable
{
public FooEnvironment()
{
// start up C API
}
public bool Dispose()
{
// shutdown C API (from same thread ctor was called on)
}
~FooEnvironment()
{
// try to shutdown C API but deadlock!
}
}
I've tried various things where we Run with the ExecutionContext from the initializing thread, but this doesn't work (at least in IIS) and we get an invalid operation exception stating that this execution context can't be used (ostensibly because it may have been marashalled across AppDomains, which seems likely).
I've read several things basically stating that what I'm trying to do can't be done but I figured I would ask since there isn't a lot of information on this topic.
Back in the old days I developed a library that wrapped the hideous DDEML which is a Win32 api wrapper around the DDE protocol. The DDEML has thread affinity requirements as well so I feel your pain.
The only strategy that is going to work is to create a dedicate thread that executes all of your library calls. This means biting the bullet and marshaling every single request to call into this API onto this dedicated thread and then marshaling back the result to the original thread. It sucks and its slow, but it is the only method guaranteed to work.
It can be done, but it is painful. You can see how I tackled the problem in my NDde library. Basically, the finalizer will simply post a message via static method calls to a thread that can accept and dispatch them to the appropriate API call. In my case I created a thread that called Application.Run to listen for messages because DDE required a Windows message loop anyway. In your case you will want to create the thread in a manner that monitors a custom message queue. This is not terribly difficult if you use the BlockingCollection class because the Take method blocks until an item appears the queue.
MSDN on migrating legacy multithreaded applications (from this page on exception handling in threads):
In general, the change will expose previously unrecognized programming problems so that they can be fixed. In some cases, however, programmers might have taken advantage of the runtime backstop, for example to terminate threads. Depending on the situation, they should consider one of the following migration strategies:
Restructure the code so the thread exits gracefully when a signal is received.
Use the Thread.Abort method to abort the thread.
If a thread must to be stopped so that process termination can proceed, make the thread a background thread so that it is automatically terminated on process exit.
In all cases, the strategy should follow the design guidelines for exceptions. See Design Guidelines for Exceptions.
This suggests that using Thread.Abort is an appropriate way to terminate a thread. Has something changed while I wasn't looking? The last I'd heard was this could cause unexpected behaviours so shouldn't be used.
Thread.Abort is a lot safer than it used to be for the following reasons.
The runtime will defer aborts while execution is in unmanaged code.
The abort will allow finally blocks to execute.
However, there is still a problem with exactly when the ThreadAbortException gets injected. Consider this code.
public class Example
{
private DateTime value = DateTime.MinValue;
public void DoSomething()
{
try
{
value = DateTime.UtcNow;
}
finally
{
}
}
}
If this code were running on a 32-bit platform the value variable could be corrupted if Thread.Abort was called and the ThreadAbortException were injected in the middle of the write to value. Since DateTime is 8 bytes the write has to take place using more than one instruction.
It is possible to guard against this by placing critical code in a finally block and by using Constrained Execution Regions, but it would be incredibly difficult to get right for all but the simplest types your define. And even then you cannot just put everything in a finally block.
Generally speaking, Thread.Abort will kill threads, leaving the data they were processing at the time in an unknown state. The state being unknown, it's usually not safe to deal with that data anymore. However, when you're trying to terminate a process, you are not expecting to deal with that thread's data anymore, so why not abort it?
Well, the problem with Thread.Abort() is that will abort the thread possibly in the middle of work. That might cause your state to be corrupted. That's why is advisable to use a volatile bool flag to control the thread, and let the thread finish its task gracefully, but based on that flag.
For more details, I recall this blog post.
As part of a large automation process, we are calling a third-party API that does some work calling services on another machine. We discovered recently that every so often when the other machine is unavailable, the API call will spin away sometimes up to 40 minutes while attempting to connect to the remote server.
The API we're using doesn't offer a way to specify a timeout and we don't want our program waiting around for that long, so I thought threads would be a nice way to enforce the timeout. The resulting code looks something like:
Thread _thread = new Thread(_caller.CallServices());
_thread.Start();
_thread.Join(timeout);
if (_thread.IsAlive)
{
_thread.Abort();
throw new Exception("Timed-out attempting to connect.");
}
Basically, I want to let APICall() run, but if it is still going after timeout has elapsed, assume it is going to fail, kill it and move on.
Since I'm new to threading in C# and on the .net runtime I thought I'd ask two related questions:
Is there a better/more appropriate mechanism in the .net libraries for what I'm trying to do, and have I committed any threading gotchas in that bit of code?
Thread.Abort() is a request for the thread to abort, and gives no guarantee that it will do so in a timely manner. It is also considered bad practice (it will throw a thread abort exception in the aborted thread, but it seems like the 3rd party API offers you no other choices.
If you know (programmatically) the address of the remote service host you should ping it before you transfer control to the 3rd party API.
If not using a backgroundworker, you could set the thread's IsBackgroundThread to true, so it doesn't keep your program from terminating.
Bad idea. Thread.Abort doesn't necessarily clean up the mess left by such an interrupted API call.
If the call is expensive, consider writing a separate .exe that makes the call, and pass the arguments to/from it using the command line or temporary files. You can kill an .exe much more safely than killing a thread.
You can also just use a delegate... Create a delegate for the method that does the work, Then call BeginInvoke on the delegate, passing it the arguments, and a callback function to handle the return values (if you want)...
Immediately after the BeginInvoke you can wait a designated time for the asynch delegate to finish, and if it does not in that specified time, move on...
public delegate [ReturnType] CallerServiceDelegate
([parameter list for_caller.CallService]);
CallerServiceDelegate callSvcDel = _caller.CallService;
DateTime cutoffDate = DateTime.Now.AddSeconds(timeoutSeconds);
IAsyncResult aR = callSvcDel.BeginInvoke([here put parameters],
AsynchCallback, null);
while (!aR.IsCompleted && DateTime.Now < cutoffDate)
Thread.Sleep(500);
if (aR.IsCompleted)
{
ReturnType returnValue = callSvcDel.EndInvoke(aR);
// whatever else you need to do to handle success
}
else
{
callSvcDel.EndInvoke(aR);
// whatever you need to do to handle timeout
}
NOTE: as written AsynchCallback could be null, as the code retrieves the return value from the EndInvoke(), but if you want to you can have the CallService() method call the AsynchCallback delegate and pass it the return values instaed...
It might work, but nobody could say for sure without an understanding of the third-party API. Aborting the thread like that could leave the component in some invalid state that it might not be able to recover from, or maybe it won't free resources that it allocated (think - what if one of your routines just stopped executing half-way through. Could you make any guarantees about the state your program would be in?).
As Cicil suggested, it might be a good idea to ping the server first.
Does your application run for long periods of time or is it more of a run-as-needed application? If it's the latter, I personally would consider using the Thread.Abort() option. While it may not be the most desirable from a purist's perspective (resource management, etc.), it is certainly straightforward to implement and may foot the bill given the way your particular application works.
The idea of a separate executable makes sense. Perhaps another option would be to use AppDomains. I'm not an expert in this area (I welcome refinements/corrections to this), but as I understand it, you'd put the API call in a separate DLL and load it into a separate AppDomain. When the API call is finished or you have to abort it, you can unload the AppDomain along with the DLL. This may have the added benefit of cleaning up resources that a straightforward Thread.Abort() will not.