I' trying to implement a fault recovery mechanism which will dispose a WCF connection on error (and then periodically attempt to reconnect and retry)
Essentially the relevant code is just
try
{
_client.DoSomthing();
}
catch
{
_client.Dispose();
}
The problem is that the above code runs inside a TPL dataflow block and must be thread safe. I'm having problems with the client being disposed while in use by other threads. I don't really want to put a lock around the whole thing as I then lose concurrent uploads and performance suffers.
I'm looking for some way to block new threads using the client but not try to dispose until I know any current calls are completed. And then to ensure that only one thread performs the dispose.
I'm imaging some mechanism along the lines of below (pseudo) code
using (var counter = new ThreadCounter())
{
try
{
if (!faulted)
_client.DoSomthing();
}
catch
{
faulted = true;
counter.BlockNewThreadsEntering()
if (counter == 1)
_client.Dispose();
}
}
Is there anything in the framework that would let me achieve this? Or any other suggestions?
Or any other suggestions?
Just follow the rule "one thread - one client". There's no reason to share database connections, http clients, service clients and so on between threads.
As a rule, all of these objects has a tiny state, and any efforts to minimize resource usage via sharing them is a headache, since you need to synchronize cross-thread access to prevent objects' state from corruption.
If your code considers system resources while creating new threads (thus, doesn't create 100 threads running on 4 CPU cores), one service client per thread isn't a problem.
Related
We have a WCF web service operation that is used to generate PDF files. We're using a 3rd party tool to do that (Syncfusion specifically) which we may not be able to replace at the moment.
The problem is that it seems that 3rd party tool has a problem with multi-threading and doesn't work in some cases when there's multiple calls to the web service at the same time.
We can get rid of the problem by using lock and making sure that only one thread executes the critical section:
Public Class GeneratorController
{
// object we use for lock
private static Object thisLock = new Object();
public void Generate(ref PdfDocument pdfDocument)
{
lock (thisLock)
{
// critical section
}
}
}
My questions is: is that a good idea? Is it going to cause any problems if we have a code like that in a web service?
Note
This is not a question about Syncfusion. This is a question about using lock in a web service. Do not change tags to syncfusion, please.
The problem I see here is resource starvation.
There is no FIFO rule surrounding locks. So if there's a continuous load, you could get this scenario:
Thread A claims the lock
Thread B waits for the lock
Thread C waits for the lock
Thread A releases the lock. The lock is arbitrarily given to thread C
Thread D waits for the lock. Now you have thread B and D both waiting.
Thread C releases the lock. Even through thread B has been waiting the longest, the lock is arbitrarily given to thread D.
And so it continues until the WCF call times out, and you get an impossible-to-reproduce error.
If I had to implement this, I would have a single worker thread dedicated to generating the PDF files. This thread would be launched when the service first starts up, and it waits to pick up a job off a job queue. Each WCF query will place a request on this queue, and there will be some way it can block until it knows the job has been processed.
.NET 4.0 provides the BlockingCollection class to help with this. (See this question)
This gives you the approach without a complete solution because it isn't a trivial problem. Good luck!
WCF supports synchronized calling of your service objects, depending on your needs, you may want to look into the following two properties:
ServiceBehavior.InstanceContextMode:
http://msdn.microsoft.com/en-us/library/system.servicemodel.servicebehaviorattribute.instancecontextmode.aspx
ServiceBehavior.ConcurrencyMode:
http://msdn.microsoft.com/en-us/library/system.servicemodel.servicebehaviorattribute.concurrencymode.aspx
If you cannot launch multiple instances of 3rd party component, and the component does not allow concurrent acccess (the worst case), then you can specify InstanceContextMode = Single, and ConcurrencyMode = Single; In this case, WCF will only instantiate a single copy of your WCF object (which I assume is a wrapper around 3rd party component), and only one request is processed at a time. The requests will be queued up and processed in a FIFO manner. You don't have to use lock inside your wcf service, since the WCF runtime makes sure you have synchronized access to your wcf objects.
Essential PDF is a thread safe component
, so it is possible to create the PDF document in multi-threaded state. Can you please create a Direct-trac incident in order to get the solution.
I am writing a server application which processes request from multiple clients. For the processing of requests I am using the threadpool.
Some of these requests modify a database record, and I want to restrict the access to that specific record to one threadpool thread at a time. For this I am using named semaphores (other processes are also accessing these records).
For each new request that wants to modify a record, the thread should wait in line for its turn.
And this is where the question comes in:
As I don't want the threadpool to fill up with threads waiting for access to a record, I found the RegisterWaitForSingleObject method in the threadpool.
But when I read the documentation (MSDN) under the section Remarks:
New wait threads are created automatically when required. ...
Does this mean that the threadpool will fill up with wait-threads? And how does this affect the performance of the threadpool?
Any other suggestions to boost performance is more than welcome!
Thanks!
Your solution is a viable option. In the absence of more specific details I do not think I can offer other tangible options. However, let me try to illustrate why I think your current solution is, at the very least, based on sound theory.
Lets say you have 64 requests that came in simultaneously. It is reasonable to assume that the thread pool could dispatch each one of those requests to a thread immediately. So you might have 64 threads that immediately begin processing. Now lets assume that the mutex has already been acquired by another thread and it is held for a really long time. That means those 64 threads will be blocked for a long time waiting for the thread that currently owns the mutex to release it. That means those 64 threads are wasted on doing nothing.
On the other hand, if you choose to use RegisterWaitForSingleObject as opposed to using a blocking call to wait for the mutex to be released then you can immediately release those 64 waiting threads (work items) and allow them to be put back into the pool. If I were to implement my own version of RegisterWaitForSingleObject then I would use the WaitHandle.WaitAny method which allows me to specify up to 64 handles (I did not randomly choose 64 for the number of requests afterall) in a single blocking method call. I am not saying it would be easy, but I could replace my 64 waiting threads for only a single thread from the pool. I do not know how Microsoft implemented the RegisterWaitForSingleObject method, but I am guessing they did it in a manner that is at least as efficient as my strategy. To put this another way, you should be able to reduce the number of pending work items in the thread pool by at least a factor of 64 by using RegisterWaitForSingleObject.
So you see, your solution is based on sound theory. I am not saying that your solution is optimal, but I do believe your concern is unwarranted in regards to the specific question asked.
IMHO you should let the database do its own synchronization. All you need to do is to ensure that you're sync'ed within your process.
Interlocked class might be a premature optimization that is too complex to implement. I would recommend using higher-level sync objects, such as ReaderWriterLockSlim. Or better yet, a Monitor.
An approach to this problem that I've used before is to have the first thread that gets one of these work items be responsible for any other ones that occur while it's processing the work item(s), This is done by queueing the work items then dropping into a critical section to process the queue. Only the 'first' thread will drop into the critical section. If a thread can't get the critical section, it'll leave and let the thread already operating in the critical section handle the queued object.
It's really not very complicated - the only thing that might not be obvious is that when leaving the critical section, the processing thread has to do it in a way that doesn't potentially leave a late-arriving workitem on the queue. Basically, the 'processing' critical section lock has to be released while holding the queue lock. If not for this one requirement, a synchronized queue would be sufficient, and the code would really be simple!
Pseudo code:
// `workitem` is an object that contains the database modification request
//
// `queue` is a Queue<T> that can hold these workitem requests
//
// `processing_lock` is an object use to provide a lock
// to indicate a thread is processing the queue
// any number of threads can call this function, but only one
// will end up processing all the workitems.
//
// The other threads will simply drop the workitem in the queue
// and leave
void threadpoolHandleDatabaseUpdateRequest(workitem)
{
// put the workitem on a queue
Monitor.Enter(queue.SyncRoot);
queue.Enqueue(workitem);
Monitor.Exit(queue.SyncRoot);
bool doProcessing;
Monitor.TryEnter(processing_queue, doProcessing);
if (!doProcessing) {
// another thread has the processing lock, it'll
// handle the workitem
return;
}
for (;;) {
Monitor.Enter(queue.SyncRoot);
if (queue.Count() == 0) {
// done processing the queue
// release locks in an order that ensures
// a workitem won't get stranded on the queue
Monitor.Exit(processing_queue);
Monitor.Exit(queue.SyncRoot);
break;
}
workitem = queue.Dequeue();
Monitor.Exit(queue.SyncRoot);
// this will get the database mutex, do the update and release
// the database mutex
doDatabaseModification(workitem);
}
}
ThreadPool creates a wait thread for ~64 waitable objects.
Good comments are here: Thread.sleep vs Monitor.Wait vs RegisteredWaitHandle?
Here's the setup: I'm trying to make a relatively simple Winforms app, a feed reader using the FeedDotNet library. The question I have is about using the threadpool. Since FeedDotNet is making synchronous HttpWebRequests, it is blocking the GUI thread. So the best thing seemed like putting the synchronous call on a ThreadPool thread, and while it is working, invoke the controls that need updating on the form. Some rough code:
private void ThreadProc(object state)
{
Interlocked.Increment(ref updatesPending);
// check that main form isn't closed/closing so that we don't get an ObjectDisposedException exception
if (this.IsDisposed || !this.IsHandleCreated) return;
if (this.InvokeRequired)
this.Invoke((MethodInvoker)delegate
{
if (!marqueeProgressBar.Visible)
this.marqueeProgressBar.Visible = true;
});
ThreadAction t = state as ThreadAction;
Feed feed = FeedReader.Read(t.XmlUri);
Interlocked.Decrement(ref updatesPending);
if (this.IsDisposed || !this.IsHandleCreated) return;
if (this.InvokeRequired)
this.Invoke((MethodInvoker)delegate { ProcessFeedResult(feed, t.Action, t.Node); });
// finished everything, hide progress bar
if (updatesPending == 0)
{
if (this.IsDisposed || !this.IsHandleCreated) return;
if (this.InvokeRequired)
this.Invoke((MethodInvoker)delegate { this.marqueeProgressBar.Visible = false; });
}
}
this = main form instance
updatesPending = volatile int in the main form
ProcessFeedResult = method that does some operations on the Feed object. Since a threadpool thread can't return a result, is this an acceptable way of processing the result via the main thread?
The main thing I'm worried about is how this scales. I've tried ~250 requests at once. The max number of threads I've seen was around 53 and once all threads were completed, back to 21. I recall in one exceptional instance of me playing around with the code, I had seen it rise as high as 120. This isn't normal, is it? Also, being on Windows XP, I reckon that with such high number of connections, there would be a bottleneck somewhere. Am I right?
What can I do to ensure maximum efficiency of threads/connections?
Having all these questions also made me wonder whether this is the right case for a Threadpool use. MSDN and other sources say it should be used for "short-lived" tasks. Is 1-2 seconds "short-lived" enough, considering I'm on a relatively fast connection? What if the user is on a 56K dial-up and one request could take from 5-12 seconds and ever more. Would the threadpool be an efficient solution then too?
The ThreadPool, unchecked is probably a bad idea.
Out of the box you get 250 threads in the threadpool per cpu.
Imagine if in a single burst you flatten out someones net connection and get them banned from getting notifications from a site cause they are suspected to be running a DoS attack.
Instead, when downloading stuff from the net you should build in tons of control. The user should be able to decide how many concurrent requests they make (and how many concurrent requests per domain), ideally you also want to offer controls for the amount of bandwidth.
Though this could be orchestrated with the ThreadPool, having dedicated threads or using something like a bunch of instances of the BackgroundWorker class is a better option.
My understanding of the ThreadPool is that it is designed for this type of situation. I think the definition of short-lived is of this order of time - perhaps even up to minutes. A "long-lived" thread would be one that was alive for the lifetime of the application.
Don't forget Microsoft would have spent some getting the efficiency of the ThreadPool as high as it could. Do you think that you could write something that was more efficient? I know I couldn't.
The .NET thread pool is designed specifically for executing short-running tasks for which the overhead of creating a new thread would negate the benefits of creating a new thread. It is not designed for tasks which block for prolonged periods or have a long execution time.
The idea is to for a task to hop onto a thread, run quickly, complete and hop off.
The BackgroundWorker class provides an easy way to execute tasks on a thread pool thread, and provides mechanisms for the task to report progress and handle cancel requests.
In this MSDN article on the BackgroundWorker Component, file downloads are explicitly given as examples of the appropriate use of this class. That should hopefully encourage you to use this class to perform the work you need.
If you're worried about overusing the thread pool, you can be assured the runtime does manage the number of available threads based on demand. Tasks are queued on the thread pool for execution. When a thread becomes available to do work, the task is loaded onto the thread. At regular intervals, a monitoring process checks the state of the thread pool. If there are tasks waiting to be executed, it can create more threads. If there are several idle threads, it can shut down some to release resources.
In a worse-case scenario, where all threads are busy and you have work queued up, the runtime will be adding threads to deal with the extra workload. The application will be running more slowly as it has to wait for more threads to be made available, but it will continue to run.
A few points, and to combine info form a few other answers:
your ThreadProc does not contain Exception handling. You should add that or 1 I/O error will halt your process.
Sam Saffron is quite right that you should limit the number of threads. You could use a (ThreadSafe) Queue to push your feeds into (WorkItems) and have 1+ threads reading from the queue in a loop.
The BackgrounWorker might be a good idea, it would provide you with both the Exception handling and Synchronization you need.
And the BackgrounWorker uses the ThreadPool, and that is fine
You may want to take a look to the "BackgroundWorker" class.
SO users,
I have 3 threads running simultaneously at any given time, trouble is after thread 1 tries to connect to a server by passing a username to it thread 2 is being invoked and by the time its thread 1's turn the server closes its connection on the code.
Is there anywhere I can implement sending username and password simultaneously with out threads interrupting each other at this time?
Thx!,
Nidhi
I very much doubt that it's genuinely thread contention which is the problem here.
Threads timeslice very quickly, and the server would have to have a ridiculously short timeout for your diagnosis to be correct.
My guess is there's something different wrong with your code, but we can't really tell what it is without seeing some code.
threads typically swap on the order of milliseconds, so i don't think thats whats causing your program to disconnect.
That said, you can implement locks/mutexes to ensure that critical code is executed without other threads executing their code, and even use thread prioritization to ensure one thread gets priority over others - but you cannot force a thread not to yield, the operating system can decide you've run long enough and force you to yield regardless. Besides, the behavior your looking for is more or less explicitly prevented in all modern schedules to prevent starvation of other processes.
It looks like you're trying to multiplex multiple data streams on one socket. So you may be running into a thread switching problem while waiting for the server, but if that's the case you're probably doing something like this, which is an inappropriate way to multithread.
void Task(int type)
{
// Authenticate
// Send Data
// Disconnect
}
// Connect
Thread.Start(Task(1));
Thread.Start(Task(2));
Thread.Start(Task(3));
If you've got threads 1, 2, and 3 doing work on the server in tandem you've got a few ways to do it:
1.) Do your work threaded with different connections
void Task(int type)
{
// Connect
// Authenticate
// Send Data
// Disconnect
}
Thread.Start(Task(1));
Thread.Start(Task(2));
Thread.Start(Task(3));
2.) Do your work singlethreaded with one connection
void Task(int type)
{
// Send Data
}
// Connect
// Authenticate
Task(1);
Task(2);
Task(3);
// Disconnect
3.) Use multiple connections
A few words about an ongoing design and implementation
I send a lot of requests to the remote application (running on a different
host, of course), and the application send back data.
About client
Client is a UI that spawn a separate thread to submit and process the requests. Once it submits all the requests, it calls Wait. And the Wait will parse all events coming the app and invoke client's callbacks.
Below is the implementation of Wait.
public void Wait (uint milliseconds)
{
while(_socket.IsConnected)
{
if (_socket.Poll(milliseconds, SelectMode.SelectRead))
{
// read info of the buffer and calls registered callbacks for the client
if(_socket.IsAvailable > 0)
ProcessSocket(socket);
}
else
return; //returns after Poll has expired
}
}
The Wait is called from a separate thread, responsible for managing network connection: both inbound and outbound traffic:
_Receiver = new Thread(DoWork);
_Receiver.IsBackground = true;
_Receiver.Start(this);
This thread is created from UI component of the application.
The issue:
client sometimes sees delays in callbacks even though main application has sent the data on time. Notably, one the message in Poll was delayed until I client disconnected, and internally I called:
_socket.Shutdown(SocketShutdown.Both);
I think something funky is happening in the Poll
Any suggestions on how to fix the issue or an alternative workaround?
Thanks
please let me know if anything is unclear
A couple of things. First, in your example, is there a difference between "_socket" and "socket"? Second, you are using the System.Net.Sockets.Socket class, right? I don't see IsConnected or IsAvailable properties on that class in the MSDN documentation for any .NET version going back to 1.1. I assume these are both typing mistakes, right?
Have you tried putting an "else" clause on the "IsAvailable > 0" test and writing a message to the Console/Output window, e.g.,
if (_socket.IsAvailable > 0) {
ProcessSocket(socket);
} else {
Console.WriteLine("Poll() returned true but there is no data");
}
This might give you an idea of what might be going on in the larger context of your program.
Aside from that, I'm not a big fan of polling sockets for data. As an alternative, is there a reason not to use the asynchronous Begin/EndReceive functions on the socket? I think it'd be straightforward to convert to the asynchronous model given the fact that you're already using a separate thread to send and receive your data. Here is an example from MSDN. Additionally, I've added the typical implementation that I use of this mechanism to this SO post.
What thread is calling the Wait() method? If you're just throwing it into the UI threadpool, that may be why you experience delays sometimes. If this is your problem, then either use the system threadpool, create a new one just for the networking parts of your application, or spawn a dedicated thread for it.
Beyond this, it's hard to help you much without seeing more code.