I have a C# Winforms application that talks to a USB device through a vendor library. I run this interface with a background thread. During the vendor constructor, the entire Winforms application GUI is frozen. One core of the CPU is at 100%, but the other cores are idle. How do I determine what calls the vendor is making to block the GUI?
I run the background thread like this -
public HardwareInterfaceClass() {
var hardwareThread = new Thread(HardwareInterfaceThread);
hardwareThread.IsBackground = true;
hardwareThread.Name = "USB Interface Communication";
hardwareThread.Start();
return
}
private void HardwareInterfaceThread() {
var usbInterface = new USBInterfaceHardware(0); // Takes 5 seconds and blocks GUI
...
}
There is nothing at all in the code you posted that would block the UI thread. So there are two possibilities:
There is something in the library code you are calling that is blocking the UI thread.
The UI thread is not really blocked.
It's impossible to know for sure which is correct, though the first option would be very unusual, especially if you hadn't actually passed anything to the library code that would even tell it where your UI thread is (but not impossible…it could have logic internally that seeks out your UI thread and somehow messes with it).
If the second option is correct, then the UI could seem to be blocked, but simply not getting enough CPU. The fact that your other CPU cores are idle suggests this isn't the problem, but given how remote the first possibility is, it's worth at least considering.
If your background thread is taking CPU time away from the UI thread, then you can fix that by setting hardwareThread.Priority = ThreadPriority.BelowNormal;. Indeed, this is a good idea to do for any thread that spins consuming 100% of a core's CPU time.
There is, of course, a third possibility: in your own code, you have somehow caused the UI thread to be blocked while this background thread is working. But without a concise, complete code example it would be impossible to explain where that is. We can only look at the code you posted, and that code doesn't block the UI anywhere.
Related
I have some code which interops with some COM dlls and ActiveX controls, and then fetches me some result. I am trying to run this code in the background in another thread.
But I have a problem, if I use UI thread to achieve this, the application gets blocked, but the time taken is about 5-6 seconds approximately for this operation.
If I move this code into a background thread, the UI remains responsive but the time taken almost doubles to 10-11 seconds. There is nothing different which I am doing, but is there any specific reason why this takes more time.
As of now not able to put any code. I tried increasing the thread priority too. It did not help.
Thanks
You should probably profile this to see when the execution of that background thread actually starts, and what it's actual time-consumption is - start to finish. There're a number of pretty decent profilers that can do this for you. Remember, when you create a separate thread, that doesn't mean that it necessarily fires up right at that instant. And something might be interrupting it (such as something higher in priority). Plus, when you executed it on your UI thread, it had your UI thread's priority: what priority are you setting the background-thread to? As DeveloperGuo suggests - you should probably instantiate the COM object on that background thread: if that object doesn't have to hang around, then it is generally cleaner and more efficient to make that thread have full responsibility for the COM objects and other resources that it uses, and just provide a higher-level abstract API for the rest of your program-code to use. These are just generic suggestions - can't get more specific without seeing code.
I am going through some code right now that is not mine. In the code there is a thread with the following code:
while (true)
{
Thread.sleep(int.MaxValue);
}
It also catches InterruptedException and goes right back into the loop, so the loop can't even be interrupted.
Does anyone know why this thread would exist, what the purpose is?
EDIT: The full code, for a little bit more context:
using IKVM.Attributes;
using java.lang;
using System;
using System.Runtime.CompilerServices;
namespace applicationNamespace
{
internal sealed class DedicatedServerSleepThread : Thread
{
internal DedicatedServer theDecitatedServer;
[MethodImpl(MethodImplOptions.NoInlining)]
internal DedicatedServerSleepThread(DedicatedServer dedicatedServer)
{
this.theDecitatedServer = dedicatedServer;
base.setDaemon(true);
this.start();
}
[MethodImpl(MethodImplOptions.NoInlining)]
public override void run()
{
while (true)
{
try
{
while (true)
{
System.Threading.Thread.Sleep(int.MaxValue);
}
}
catch (System.Threading.ThreadInterruptedException)
{
}
}
}
static DedicatedServerSleepThread()
{
}
}
}
Note that the earlier code uses some non-standard libraries, so the lowercase sleep was valid. Specifically it was using ikvm libraries (which are based on java standard libraries, and used to cross-compile java programs to .net)
This was a java server program that I cross-compiled to .net bytecode and then decompiled. I wasn't sure if anyone had ever seen a thread dedicated to sleeping for any reason, and if so what the reason was. ta.speot.is for giving a really good answer.
Let's ignore the code you posted, since it won't compile, and just focus on whether a thread that sleeps forever serves any purpose.
There's three reasons I can think of for a thread whose job is to sleep, none of them are particularly legitimate.
To Do Nothing
The thread might exist to do nothing meaningful, forever. If someone tasked you with the job of creating a thread that should not do anything meaningful, ever, you might come up with that code.
To Keep The CLR/Process Alive
If it's a foreground thread, the thread will keep the process and CLR alive, even if the main thread completes. From MSDN:
A managed thread is either a background thread or a foreground thread. Background threads are identical to foreground threads with one exception: a background thread does not keep the managed execution environment running. Once all foreground threads have been stopped in a managed process (where the .exe file is a managed assembly), the system stops all background threads and shuts down.
To Cool Down
It's possible that by tying up a thread with sleep, other threads which can do meaningful work are not started as frequently (e.g. if they're being scheduled inside a threadpool or other environment). From The Daily WTF:
Due to a bunch of data-crunching speedups, the cpu's no longer have a chance to throttle down. The heat built up in the server, a fan controller fried and the cpu's cooked. As an alternative to purchasing redundant cooling, they made me slow the application down to previous performance levels with strategically placed sleeps.
The code, as written (except with Sleep capitalized), will only serve the purpose of making a thread that does nothing, and uses up some extra memory (for the thread's stack data).
It's possible that the thread was intended to perform some other function, but it's likely something that should have been handled in another manner.
From what you have shown us it just creates a thread and makes it sleep forever. Without more context we can't tell you anything else
I'm building a WPF app which will do some heavy work in the background. The issue is that when I run the task in the unit tests, it usually takes about 6~7s to run. But when I run it using TPL in WPF app, it takes somewhere between 12s~30s to run. Is there a way to speed up this thing. I'm calling COM api of LogParser to do the real work.
Update:
My code for calling Log Parser API looks like below
var thread = new Thread(() =>
{
var logQuery = new LogQueryClassClass();
var inputFormat = new COMEventLogInputContextClassClass
{
direction = "FW",
fullText = true,
resolveSIDs = false,
formatMessage = true,
formatMsg = true,
msgErrorMode = "MSG",
fullEventCode = false,
stringsSep = "|",
iCheckpoint = string.Empty,
binaryFormat = "HEX"
};
try
{
Debug.AutoFlush = true;
var watch = Stopwatch.StartNew();
var recordset = logQuery.Execute(query, inputFormat);
watch.Stop();
watch = Stopwatch.StartNew();
while (!recordset.atEnd())
{
var record = recordset.getRecord();
recordProcessor(record);
recordset.moveNext();
}
recordset.close();
watch.Stop();
}
catch
{
}
finally
{
if (logQuery != null)
{
Marshal.ReleaseComObject(logQuery);
GC.SuppressFinalize(logQuery);
logQuery = null;
}
}
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join();
The thing now is with this change, I can see about 3 - 4s improvement in debugging mode, but not when I hit Ctrl + F5 to run it which is quite beyond me. How come??
The problem here is that the COM object you're using will only run on an STA thread. Several people already suggested this, but I decided to check, just to be sure. I installed the LogParser SDK, and here's what it puts in the registry for the CLSID associated with the MSUtil.LogQuery ProgID:
[HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{8CFEBA94-3FC2-45CA-B9A5-9EDACF704F66}]
#="LogQuery"
"AppID"="{3040E2D1-C692-4081-91BB-75F08FEE0EF6}"
[HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{8CFEBA94-3FC2-45CA-B9A5-9EDACF704F66}\InprocServer32]
#="C:\\Program Files (x86)\\Log Parser 2.2\\LogParser.dll"
"ThreadingModel"="Apartment"
[HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{8CFEBA94-3FC2-45CA-B9A5-9EDACF704F66}\ProgID]
#="MSUtil.LogQuery.1"
[HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{8CFEBA94-3FC2-45CA-B9A5-9EDACF704F66}\VersionIndependentProgID]
#="MSUtil.LogQuery"
It's that "ThreadingModel"="Apartment" that's the clincher. This COM class is declaring that it can only run on an STA thread.
Both the TPL and the BackgroundWorker use MTA threads. The consequence of this is that when you use the LogParser from either a TPL task or a BackgroundWorker the COM runtime detects that you're on the wrong kind of thread, and will either find or create an STA to host the object. (In this particular case it'll use what's called the 'host STA', a thread that COM creates specially for this purpose. There are some scenarios in which it'll use your main UI thread instead, but that's not the case here.)
COM then automatically marshals any calls from your worker thread over to that STA thread. It does this via a Windows message queue, so for each method you execute (and remember, property accessors are just methods in disguise, so this applies to property use too), your worker thread will send a message to that STA thread, that STA thread's message pump then has to pick that message up and dispatch it, at which point the COM runtime will call the method on the LogParser for you.
This is slow if you've got an API that involves a high volume of calls.
This is neither a WPF nor a Windows Forms issue by the way. It is entirely to do with using an STA-based COM object from a non-STA thread. You could reproduce exactly the same problem with a console app too, if you were using a non-STA thread in that. And the problem isn't specific to either the TPL or the BackgroundWorker - it will afflict anything that uses the thread pool, because thread pool threads all use MTA, not STA.
The solution is to use an STA thread. And the best way to do that is create a dedicated thread. Use the Thread class in the System.Threading namespace to launch your own thread. Call its SetApartmentState method before starting it. Make sure that the code that creates instances of objects from the LogParser API is running on that thread, and also make sure that you only ever use those objects from that thread. This should fix your performance issues.
Edited 21st Feb 2013 to clarify:
Note that it's not simply enough to ensure that you are using the COM object from an STA thread. You must use if from the same STA thread on which you created it. Basically, the whole reason for having the STA model is to enable COM components to use a single-threaded model. It enables them to assume that everything that happens to them happens on one thread. If you write multi-threaded .NET code that uses an STA thread from multiple threads, it will, under the covers, ensure that the COM object gets what it wants, meaning that all access will go through the thread it belongs to.
This means that if you call it from some other thread than its home STA thread, then even if that other thread also happens to be an STA thread, you'll still be paying the cross-thread price.
Edited 25th Feb 2013 to add:
(Not sure if this is relevant to this particular question, but could well be of interest to other people landing on this question through a search.) A downside of moving work onto a separate worker thread is that if you want to update the UI in any way as a result of processing these records, you're now on the wrong thread. If you're using databinding an INotifyPropertyChanged, WPF will automatically handle the cross-thread change notification for you, but this can have significant performance implications. If you need to do a lot of work on a background thread, but that work needs to end up updating the UI, you may need to take steps to batch those updates. It's not completely trivial - see the series of blog entries starting here: http://www.interact-sw.co.uk/iangblog/2013/02/14/wpf-async-too-fast
COM uses message queues for IPC. I'm unclear what determines which message queue, but I suspect it's the shell message queue because the Delphi debugger and Outlook used to play merry hell with each other. My unproven hypothesis is that an out of process COM server can be stalled by something else stallings the shell message queue. Windows has timeouts to prevent this sort of thing from totally locking up the system but it can cause massive slowdown in affected processes. My solution would be to avoid COM. You could check this by commenting out the parts that actually use COM and timing the process.
In my C# project I have a form that is displayed which shows a progress bar.
Some processing is then done which involves communication over the internet.
While this processing is occurring the form says "Not Responding" when run in Win 7, in XP the form just goes white.
Either way, it is not acceptable.
Do I need to use threads to solve this problem?
What are some of the basics of threads that I would need to use in this scenario?
Your processing must be done within a thread.
Out of your thread you have to invoke your progress bar to show the progress.
progressBar1.Invoke((MethodInvoker)delegate
{
progressBar1.Value = (int)((i / limit) * 100);
});
Yes you have to use threads to keep your UI responsive while something gets done in background. But this question cannot be just answered just like "use Threads to solve it", because there are a lot of forms in which you could use threads. (Backgroundworker, Threadpool, Asynch IO, Creating a Thread, Task Parallel Library, CCR, and a lot more you could imagine for every kind of parallelization scenarios).
As you said you are doing some processing which needs connecting to internet. Where does the most amount of time spent? is it IO over network which takes most time in that case probably Asynchronous IO makes a lot of sense. If time spent is in one huge processing operation then Background worker is perfect, but if this processing can be further broken down into smaller chunks of parallel processing tasks then TPL or ThreadPool is preferred. Till now I am talking only about some processing which happens on Windows forms event, and keep the UI responsive. But based on the scenario there are numerous other options you could use to make threading work for you.
Asynch IO doesnt look like you are doing threading but it more matches with eventing model of winforms. So you could look at that if you are very comfortable with event based programming.
Threadpool looks more like a queue of workers to which you could keep throwing all the work needs to be done, and the framework figures out how many threads to run based on the kind of machine you are using (dual core, quad core etc) and it would get your work items doen in optimal way.
Bottom line its not one answer to use one over other, instead based on the kind of problem you are solving threading model needs to be decided on.
A cheaper option is to add the line Application.DoEvents() inside whatever loops your app is running, which will cause it to process messages each time it gets there.
If you use System.Net.WebClient, you can use DownloadDataAsync() to communicate in a non blocking way.
The System.Net.Sockets.Socket class proviede non blocking communication, too.
Sockets example
WebClient example
Yes, better way is use BackGroundWorker component. It is wrapper over threads, so you don't need to manage threads. You can get more info from Background worker on MSDN
As long as the program remain in the function to process something, the UI will not update. That is why you may need to start a background thread, so that your UI can continue functioning while your background thread can do the work. An alternatively is to use asynchronous functions.
example of background thread
From your description I'll assume that all your work is currently being done on a single thread, the main thread which is also used for your GUI.
The progress bar can only update when that main thread gets a chance to check its state and apply any expected changes.
Therefore it is important that your processing work does not occupy the main thread for extended periods of time.
There are two main approaches to handling this:
Stepping the processing activity.
Break down the processing step into a number of serial tasks - each short in nature.
Progressively call each of these serial tasks in the OnIdle event on your main thread.
Using a background thread.
See other answers giving more detail on how this would work.
The stepping approach can be useful if you want to avoid the sublties of thread synchronisation. The threading approach is probably better but only essential if it is impossible to guarantee serial short steps.
I'm writing a J2ME application. One of the pieces is something that polls the contents of a directory periodically, and, if there are any new things, paints them on the screen. I've done this by having the UI form launch a polling thread with a pointer back to itself, and when the polling thread finds something it calls back to the form and calls a syncrhonized method to update it's display. This seems to work fine.
The question I have is this. In C#/.NET I know it is not nice to have non-UI threads updating the UI, and the correct way to handle this is to delegate it up to the UI thread.
E.g. the following:
public void DoSomeUIThing()
{
if (this.uiComponent.InvokeRequired)
{
this.uiComponent.Invoke(someDelegateThatCallsBackToThis);
}
else
{
this.uiComponent.Text = "This is the update I want to happen";
}
}
Is there a J2ME equivalent for how to manage this process? How about Java? Or does Java/J2ME just play nicer in regard to this? If not, how is this done?
[EDIT] It appears that Swing supports what I'm asking about via the SwingUtilities.invokeLater() and invokeAndWait() methods. Is there an equivalent framework for J2ME?
Regarding Java, what you are describing looks like a SwingWorker (worker thread).
When a Swing program needs to execute a long-running task, it usually uses one of the worker threads, also known as the background threads.
A Swing program includes the following kinds of threads:
Initial threads, the threads that execute initial application code.
The event dispatch thread, where all event-handling code is executed. Most code that interacts with the Swing framework must also execute on this thread.
Worker threads, also known as background threads, where time-consuming background tasks are executed.
Single-thread rule:
Once a Swing component has been realized, all code that might affect or depend on the state of that component should be executed in the event-dispatching thread.
When used in a J2EE context, you need to be careful when you are referencing a SwingWorker from an EJB.
Regarding J2ME, it depends if you are developing your application as a standard MIDlet that will run on any MIDP-enabled device, or for instance as a RIMlet, a CLDC-based application that uses BlackBerry-specific APIs and therefore will run only on BlackBerry devices.
Because unlike MIDP's UI classes, RIM's are similar to Swing in the sense that UI operations occur on the event thread, which is not thread-safe as in MIDP. To run code on the event thread, an application must obtain a lock on the event object, or use invokeLater() or invokeAndWait() – extra work for the developer, but sophistication comes with a price tag.
But for LCDUI, you can access a form from multiple threads.
There are many profiles of Java ME. If you mean MIDP then Display.runSerially is what you want.
For AWT (Swing) you would use EventQueue.invokeLater (SwingUtilities.invokeLater is only necessary due to Java 1.1 not having the EventQueue method - 1.2 is about to celebrate its tenth birthday). For the Common DOM API, use DOMService.invokeLater.
No matter what claims a GUI API may make about thread-safety they are probably wrong (some of the claims of Swing are removed in JDK7 because they are not implementable). In any case, application code unlikely to be thread-safe.
For j2me apps you probably want to keep it simple. The main thing is to touch UI components only in the event thread. The direct way of doing this is to use invokeLater or invokeAndWait. Depending on your libraries you won't have access to anything more than that. In general if these aren't provided in your platform it probably equates to there being no thread support and not being an issue. For example the blackberry does support it.
If you develop under SWT this is accomplished by means of asyncExec() method of Display object. You pass an object implementing Runnable so the UI thread executes the changes done in other thread.
This is an example borrowed from here
public void itemRemoved(final ModelEvent me)
{
final TableViewer tableViewer = this.viewer;
if (tableViewer != null)
{
display.asyncExec(new Runnable()
{
public void run()
{
tableViewer.remove(me.getItem());
}
}
}
}
I can attest that the MIDP UI toolkit is indeed thread-safe, as I have large MIDlets with complex GUI running on millions of phones made by almost every manufacturer, and I have never seen a problem in that regard.