I know this might be a bit of a 'silly' question, but sometimes, I just want to loop until a condition is false but I don't like keeping the loop empty. So instead of:
Visible = true;
while(IsRunning)
{
}
Visible = false;
I usually prefer:
while(IsRunning)
{
Visible = true;
}
Visible = false;
However, I'm a bit concerned about what exactly happens at the line Visible = true;. Does the Runtime keep executing that statement even though it's redundant? Is it even advisable to do it this way? Many 'code-enhancements' plugins don't like empty while loops, and I don't really understand why.
SO:
Is there anything wrong with having an empty while loop?
Does having a loop such as shown above have any performance effects?
Thanks!
This is called busy or spin waiting.
The main problem is, that you are blocking the thread, that is running this while loop. If this thread is GUI thread, then it will result in freezing and unresponsible GUI. And yes, this results in loss of performance, because neither compiler, nor OS can know if they can somehow optimize this while loop.
Just try making single loop like this and see how one core of your CPU is running at 100%.
The right way to do this is to use asynchronous programming, where your code gets notified, either by event or language construct (like await) when the previous operation finished running.
But it is usually used in low-level systems or languages. .NET 4.0 introduces SpinWait construct, that serves as efficient threading sychnronization.
And in relation to your question. I believe neither should be used. They are both problematic for both debugging, performance and clarity of code.
It's not a good idea to do this. Start up the application, and when it enters this loop, take a look at the CPU usage in the task manager. You'll notice that one of the CPU cores will be running at full capacity. This means that energy is being wasted, and some other programs that may need to execute would not have as much CPU time as they could.
There are several ways around this. The simplest solution here is to put the thread to sleep for some number of milliseconds within each loop pass, like this:
Visible = true;
while(IsRunning)
{
Thread.Sleep(50 /* millisec */);
}
Visible = false;
A better solution would depend on what exactly your program is doing. If it's loading something in another thread, it may be better to either use AutoResetEvent, or through locking, or other thread synchronization mechanism.
Well..
Yes an empty while loop would generally be seen as a bad thing, though there are a few useful cases too.
Yes the CPU will execute your redundant statement
No, you should not do something like that. It uses 100% of the CPU and that is not useful.
There are alternate solutions, but without knowing your program it's hard to advise. You might however want to look into IPC and generally use blocking methods (call them in separate threads) instead of non-blocking.
Blocking methods pause your thread and give control back to the operating system which will (hopefully) do something useful with the CPU time, like putting parts of the CPU to sleep, saving power and reducing heat output.
Don't do it in main (UI thread). Try to find or make event (for ex. IsRunningChanged).
If you are need to wait something in thread it is better to use EventWaitHandle http://msdn.microsoft.com/en-us/library/system.threading.eventwaithandle.eventwaithandle.aspx
But if you need to wait for bool value you can do
while(IsRunning)
{
Thread.Sleep(10);
}
Related
I've got an application where there are several threads that provide data, that needs to go through some heavy math. The math part needs a lot of initialization, afterwards it's pretty fast - as such I can't just spawn a thread every time I need to do the calculation, nor should every source thread have its own solver (there can be a LOT of such threads, beyond a certain point the memory requirements are obscene, and the overhead gets in the way or processing power).
I would like to use a following model: The data gathering and using threads would call to a single object, through one thread-safe interface function, like
public OutData DoMath(InData data) {...}
that would take care of the rest. This would involve finding a free worker thread (or waiting and blocking till one is available) passing by some means the data in a thread safe manner to one of the free worker threads, waiting (blocking) for it to do its job and gathering the result and returning it.
The worker thread(s) would then go into some sleep/blocked state, until a new input item would appear on its interface (or a command to clean up and die).
I know how to do this by means of various convoluted locks, queues and waits in a very horrible nasty way. I'm guessing there's a better, more elegant way.
My questions are:
Is this a good architecture for this?
Are there commonly used elegant means of doing this?
The target framework is .NET 4.5 or higher.
Thank you,
David
The math part needs a lot of initialization, afterwards it's pretty fast - as such I can't just spawn a thread every time I need to do the calculation, nor should every source thread have its own solver (there can be a LOT of such threads, beyond a certain point the memory requirements are obscene, and the overhead gets in the way or processing power).
Sounds like a pool of lazy-initialized items. You can use a basic BlockingCollection for this, but I recommend overriding the default queue-like behavior with a stack-like behavior to avoid initializing contexts you may not ever need.
I'll call the expensive-to-initialize type MathContext:
private static readonly BlockingColleciton<Lazy<MathContext>> Pool;
static Constructor()
{
Pool = new BlockingCollection<Lazy<MathContext>>(new ConcurrentStack<Lazy<MathContext>>());
for (int i = 0; i != 100; ++i) // or whatever you want your upper limit to be
Pool.Add(new Lazy<MathContext>());
}
This would involve finding a free worker thread (or waiting and blocking till one is available)
Actually, there's no point in using a worker thread here. Since your interface is synchronous, the calling thread can just do the work itself.
OutData DoMath(InData data)
{
// First, take a context from the pool.
var lazyContext = Pool.Take();
try
{
// Initialize the context if necessary.
var context = lazyContext.Value;
return ... // Do the actual work.
}
finally
{
// Ensure the context is returned to the pool.
Pool.Add(lazyContext);
}
}
I also think you should check out the TPL Dataflow library. It would require a bit of code restructuring, but it sounds like it may be a good fit for your problem domain.
Investigate Task Parallel Library. It has a set of methods for creating and managing threads. And such classes as ReaderWriterLock, ManualResetEvent
and their derivatives may help in synchronizing threads
Don't use locks. This problem sounds nice for a proper nearly lock free approach.
I think what you need to look into is the BlockingCollection. This class is a powerful collection for multiple consumers and producers. If you think about using it with Parallel.ForEach you may want to look into writing your own Partitioner to get some more performance out of it. Parallel contains a couple of very nice methods if you only need a couple of threads for a relatively short time. That sounds like something you need to do. There are also overloads that provide initialization and finalization methods for each spawned thread along with passing thread local variables from one stage of the function to the next. That may really help you.
The general tips apply here of cause too. Try to split up your application in as may small parts as possible. That usually clears things up nicely and the ways how to do things become clearer.
All in all from what you told about the problem at hand I do not think that you need a lot of blocking synchronization. The BlockingCollection is only blocking the consumer threads until new data is ready to be consumed. And the producer if you limit the size...
I can't think of anything beyond that out of the top of my head. This is a very general question and without some specific issues it is hard to help beyond that.
I still hope that helps.
You've pretty much described a thread pool - fortunately, there's quite a few simple APIs you can use for that. The simplest is probably
await Task.Run(() => DoMath(inData));
or just call Task.Run(() => DoMath(inData)).GetAwaiter().GetResult() if you don't mind blocking the requesting thread.
Instead of starting a whole new thread, it will simply borrow a thread from the .NET thread pool for the computation, and then return the result. Since you're doing almost pure CPU work, the thread pool will have only as much threads as you really need (that is, about the same (or double) amount as the number of CPU cores you have).
Using the await based version is a bit trickier - you need to ensure your whole call chain returns Tasks - but it has a major advantage in avoiding the need to keep the calling thread alive while you wait for the results to be done. And even better, if you make sure the original thread is also a thread-pool thread, you don't even need the Task.Run - the threads will be balanced automatically. Since you're only doing synchronous work anyway, this turns your whole problem into simply avoiding any manual new Thread, and using Task.Run(...) instead.
First, create a pool of N such "math service objects" that are heavy. Then, guard usage of that pool with a new SemaphoreSlim(N, N). Accessing those objects is then as easy as:
SemaphoreSlim sem = ...;
//...
await sem.WaitAsync();
var obj = TakeFromPool();
DoWork(obj);
Return(obj);
sem.Release();
You can vary this pattern in many ways. The core of it is the pool plus a semaphore that can be used to wait if the pool is empty at the time.
I'm creating a physics simulation, which is meant to be realistic, and I have it working correctly, but the framerate drops off quite quickly.
I'm iterating through each of the objects, and then again for each of those objects.
I'm not sure why this would be the case, since the number of operations in each frame remains the same. The only thing of which I can think, is that the threading is the problem. I have the iteration split into four parts, and I have one quarter of the list being calculated on 4 separate threadsw, but when I check task manager, I'm only really using one core.
Here is the pertinent code:
private void Update(GameTime gameTime)
{
for (int i = 0; i < Bodies.Count; i++)
{
Bodies[i].Update(gameTime);
}
ThreadPool.QueueUserWorkItem(new WaitCallback(CalculatePhysics0));
ThreadPool.QueueUserWorkItem(new WaitCallback(CalculatePhysics1));
ThreadPool.QueueUserWorkItem(new WaitCallback(CalculatePhysics2));
ThreadPool.QueueUserWorkItem(new WaitCallback(CalculatePhysics3));
}
private void CalculatePhysics0(object o)
{
for (int i = 0; i < Bodies.Count/4; i++)
{
Body body = Bodies[i];
g.ApplyTo(ref body, Bodies);
}
}
// 3 other methods exactly the same, but iterating their portion of the list
I'm not very experienced with multithreading. I can deal with the problems that arise from its use, though. I can see that the problem may be that the ThreadPool is not a good way to achieve my desired effect, which is to iterate through the list concurrently between threads.
You can use the Task Parallel Library, which helps make most of this much easier. This should be available in XNA 4.0+
Task.Factory.StartNew(()=>CalculatePhysics0);
I believe the default behavior should work, but you can specify the TaskCreationOption
If that does not work, then you can use a TaskScheduler:
var scheduler = new TaskScheduler{MaximumConcurrencyLevel=4};
Task.Factory.StartNew(()=>CalculatePhysics0, null, TaskCreationOptions.None, scheduler);
In regards to a comment you've left on another answer: more threads != performance increase. You may be surprised how many things actually perform better in serial rather than in parallel. Of course, that doesn't mean that your code can't benefit from multiple threads on different cores, just that you shouldn't assume adding more threads will magically cause your processing throughput to increase.
It's difficult to say what will help your code perform better, without being able to look at more of it. First, it's helpful to know a little bit about the threading model in .NET. I would recommend you read about it, since I can't go into much detail here. A thread in .NET is not necessarily a native thread. That is to say that by the time you queue the third physics method in the ThreadPool, the first might be done, and so it will just use the thread already created. Of course, then there's the time where you queue a task right before another one finishes and an additional (costly) native thread has to be created. In that case, it's possible that less threads might have been better.
The idea of abstraction goes further when you look at the Task Parallel Library, where each task may seem like a thread, but really is much further from it. Many tasks can wind up running on the same thread. You can get around this by hinting to the TaskFactory that it's a long running task, ie Task.Factory.StartNew(() => DoWork(), TaskCreationOptions.LongRunning), which causes the scheduler to start this task on a new thread (this, again, might not be better than just having the runtime schedule it for you).
All this being said, if your work takes enough time to process, it will wind up running on a separate thread if you're queuing it with the ThreadPool. If the work happens fast enough, though, it would appear that only one thread or one core is being used.
What led you to the conclusion that that you're only using one core?
Was it only what you saw from Task Manager? That's hardly a conclusive result.
Did you try adding a column to the Task Manager detail tab for threads, and actually check if your code is spawning additional threads or not?
I also see that you're iterating over the array of Bodies twice, is there any particular reason you can't update the bodies with the GameTime in parallel as well (perhaps some limitation in XNA)?
All of the above is just a shot in the dark though. If you really, and I mean really want to know where any performance issues lie, you'll profile your code with a decent profiler, like Ants by RedGate, dotTrace by JetBrains, or if you have the Premium or above edition of Visual Studio, the analyzer built right into your IDE.
I'm not sure your problem is where you think it is, and in my experience, it rarely is. I hope that some of my brain dump above can be of some help to you.
Is there any way I can abstract away what thread a particular delegate may execute on, such that I could execute it on the calling thread initially, but move execution to a background thread if it ends up taking longer than a certain amount of time?
Assume the delegate is written to be asynchronous. I'm not trying to take synchronous blocks and move them to background threads to increase parallelism, but rather I'm looking to increase performance of asynchronous execution by avoiding the overhead of threads for simple operations.
Basically I'm wondering if there's any way the execution of a delegate or lambda can be paused, moved to another thread and resumed, if I could establish clear stack boundaries, etc.
I doubt this is possible, I'm just curious.
It is possible, but it would be awkward and difficult to get right. The best way to make this happen is to use coroutines. The only mechanism in .NET that currently fits the coroutine paradigm is C#'s iterators via the yield return keyword. You could theorectically hack something together that allows the execution of a method to transition from one thread to another1. However, this would be nothing less than a blog worthy hack, but I do think it is possible.2
The next best option is to go ahead and upgrade to the Async CTP. This is a feature that will be available in C# and which will allow you do exactly what you are asking for. This is accomplished elegantly with the proposed await keyword and some clever exploits that will also be included. The end result would look something like the follwing.
public async void SomeMethod()
{
// Do stuff on the calling thread.
await ThreadPool.SwitchTo(); // Switch to the ThreadPool.
// Do stuff on a ThreadPool thread now!
await MyForm.Dispatcher.SwitchTo(); // Switch to the UI thread.
// Do stuff on the UI thread now!
}
This is just one of the many wicked cool tricks you can do with the new await keyword.
1The only way you can actually inject the execution of code onto an existing thread is if the target is specifically designed to accept the injection in the form of a work item.
2You can see my answer here for one such attempt at mimicking the await keyword with iterators. The MindTouch Dream framework is another, probably better, variation. The point is that it should be possible to cause the thread switching with some ingenious hacking.
Not easily.
If you structure your delegate as a state machine, you could track execution time between states and, when you reach your desired threshold, launch the next state in a new thread.
A simpler solution would be to launch it in a new thread to start with. Any reason that's not acceptable?
(posting from my phone - I'll provide some pseudocode when I'm at a real keyboard if necessary)
No I don't think that is possible. At least not directly with regular delegates. If you created some kind of IEnumerable that yielded after a little bit of work, then you could manually run a few iterations of it and then switch to running it on a background thread after so many iterations.
The ThreadPool and TPL's Task should be plenty performant, simply always run it on a background thread. Unless you have a specific benchmark showing that using a Task causes a bunch of overhead it sounds like you are trying to prematurely optimize.
Often times I when I see some multi-threaded code, I see Thread.Sleep() statements in the code.
I even had a crash where I was trying to figure out the problem, so commented out most of the multi-threaded code and slowly brought it and for the final piece when I added a for statement like:
for ( int i = 0; i < 1000000; ++i )
++i;
it didn't crash. So now I replaced it Thread.Sleep() and it seems to work. I can't repro it easily to post it here, but is using Thread.Sleep() necessary for multi-threaded applications?
What's the purpose of them? Would it lead to unexpected results if not used?
EDIT: Btw I am using the BackgroundWorker and only implementing my stuff in there, but not sure what causes this. Although I am using an API which is the hosting app where the app is not multi threaded. So for instance I think I can't call it's API functions on several threads at once. Not sure, but that was my guess.
Typically, Thread.Sleep is a sign of a bad design. That being said, its MUCH better than eating 100% of the CPU core time, which is what the for loop above is doing.
A better option is typically to use a WaitHandle, such as a ManualResetEvent, to trigger the continuation of the thread's execution when the "event" (which is the reason to delay) occurs. Alternatively, using a Timer can work as well in many cases.
The Thread.Sleep(1) allows switch to execution another thread. So if you have more threads than cores/processors and you know "now I did in this thread a lot of work and next work can be done little-bit later" you call Thread.Sleep(1) and allows another thread to do some work sooner than the native switcher will "pause" the currently executed thread.
Try this: Write a program that launches 100 threads, and put each of the thread into a for loop as you described. And then write another that launches 100 threads and uses Thread.Sleep instead.
Run them both and compare the CPU usage. You'll see the point. =)
Thread.Sleep() simply causes the executing thread to halt for the specified duration.
I've seen many developers use Thread.Sleep() because they don't probably handle the joining of dependent threads. They simply use Thread.Sleep() to force a thread to wait for some amount of time until the think their other threads would have finished and have their data available.
If you have two threads that need to wait on each other to proceed with their processing, you should really use the mechanisms built in to .NET that are meant to handle situations like that (ie. ManualResetEvent, etc.)
Thread.Sleep() is OK to use in some situations eg. watchdog threads.
However in your case, it may not seem to be the optimal solution as pointed out by others.
Without a code sample, it's hard to tell, but based on your description, I don't think it's a question of Thread.Sleep() or not. I would suspect that you may be suffering from a race condition - that's usually why you experience "random" buggy behavior or even "random" crashes in multithreaded code - as seems to be what you are experiencing.
For whatever reason, your for-loop may cause the subtle critical timings of the race condition to occur less often, but it won't solve the root cause. There are many pitfalls to be aware of when doing multithreaded programming, I can only advice you to read up on the topic if you want to be able to avoid these.
I'll recommend reading http://www.amazon.com/Concurrent-Programming-Windows-Joe-Duffy/dp/032143482X
Okay,
There seems to be a lot of discussion on here about how terribly awful Thread.Abort() is, and how to work around using Thread.Abort() in your code by adding exit checks in your loop.
This assumes that you control how the work is being partitioned in a way that's granular enough to loop over it.
But how do I do the following:
Launch worker thread to do something while keeping the UI responsive. For all intents and purposes the code for the worker thread looks like this:
public override void Run()
{
try
{
_dataTable = ExecuteSingleGinormousSqlQuery();
} finally
{
// close the connection if it was left open.
}
}
Have "Cancel" button so that the user can interrupt this if they get bored of waiting.
It doesn't seem like there's any other way around this than with Thread.Abort(). Is that true? Furthermore, in empirical tests, it doesn't even seem like Thread.Abort() actually kills the thread until the call that is making the query, e.g.
new SqlDataAdapter(cmd).Fill( ds );
comes back in the first place, thus significantly negating its utility.
Is there a way around this? Best practices?
The SqlCommand object has a Cancel() method which you can call from another thread to attempt to cancel a running SQL query. It's not guaranteed to succeed, and will depend on the database, drivers and the actual query running, but you might find it's ok for what you need.
You're right that it won't immediately abort a thread that's busy in an interop call, which is probably why it doesn't stop until after the database call is completed. (See http://www.devx.com/codemag/Article/17442/0/page/4)
I suppose you could make the call asynchronous (see http://www.devx.com/dotnet/Article/26747) but all that means is that you don't have to abort the thread. The call continues on in the background and isn't being aborted on the database end. You might as well just use a synchronous call and let the thread complete, ignoring its results. The other issue is that you can't use a simple Fill method to do the work, if you want to go async.
I would kill the query or the connection to the database. It can be done on most servers via simple command or procedure call.
You can easily kill query in mysql issuing the following command:
KILL QUERY <query_id>
or in mssql
KILL <unit of work id>
You're the engineer. No one will throw you in jail for using Abort ().
All dangerous and/or deprecated constructs have specific circumstances where they may be desirable and sometimes necessary. This may be one such case. Mastery of any skill is knowing the rules and knowing when to break them.
But... and it's a big but... the big question is: what happens when `ExecuteSingleGinormousSqlQuery()' itself is aborted? Will it leave the client, the server or the database in a screwed up state? Are you sure you know what will happen? Do you have access to all the source code? And even if you do, have you gone over every line to make sure it's safe?
The problem with Thread.Abort () is that aborts can happen anywhere, and we know there have been bugs in the CLR that can make seemingly safe code misbehave.
I agree with Larry. As long as you're pretty sure that the SQL query won't screw up the database and it doesn't look it will cause problems elsewhere in your app by being killed off, that might be an "acceptable" use for Abort.
However, remember with this also that even if you kill the SQL, if it's one that makes updates or deletes, it will still take a while to rollback the changes and will not free up your database tables immediately on hitting cancel. Also, you might be better served to focus on optimizing the database instead by optimizing the query, adding indexes, etc, to make the Ginormous query not so long running as it apparently is.
Another option is instead of executing your long running operation in a background thread, you execute it in a new process.
There are 2 downsides:
A process has a performance penalty that is several orders of magnitude greater than that of a thread. Both in startup time and in memory overhead. In your case of a user interface scenario however, the startup time of a new background process should be negligible and can be measured as happening "in the blink of an eye."
You are required to use some form of interprocess communication method to get the results back to your main program, which is usually more complicated than sharing memory between threads.
The benefit of a process vs. thread is that the semantics of killing a process are well understood, and you are pretty much guaranteed that the process will immediately terminate and resources will not be leaked.
Peace
If you do not mind refactoring your code you could use the SqlCommand.BeginExecuteReader method or one of the other asynchronous variants.