I've created a GUI application in Powershell. It's designed to use a RunspacePool to multi-thread its requests in the background, and this works perfectly fine from PowerShell natively.
However, when I convert the file to an EXE using PS2EXE, it needs to use Single Thread Apartment (STA) since it's a GUI. It gives me errors if I try and run it as MTA. And then when the EXE runs as STA, it performs its activities at a fraction of the speed it should, as if it is still just using one thread.
Is a STA not able to initialise other threads for background tasks? Or will I need to configure the application as a MTA but explicitly hang the user interface on its own thread?
Related
I use a specific tool to inspect my app. Once the app hits a breakpoint I can invoke my tool from the Immediate Window by calling a certain function. The tool itself is a multi-threaded Windows App and therefore spawns some tasks.
The problem that I am facing is that sometimes some tasks scheduled from the tool are never run which causes my tool to hang indefinitely. I spawn tasks with ThreadPool.QueueUserWorkItem or with Task.Run and they both cause the tool to hang and never execute these tasks. If I use Thread class instead the tool works perfectly.
Also, the tool works (with Tasks) if started normally i.e. not from the Immediate Window. Therefore the problem occurs only if I use Tasks and Immediate window.
Thus, my question is what might be the reason that some tasks are never executed? I understand that Immediate Window blocks all other threads and executes the command on the thread which hit the breakpoint, but the threads/tasks spawned from the Immediate Window thread should be still executed, right?
Both my app and the tool are in C#.
I am using Visual Studio Professional 2015 Update 1.
Immediate window, in contrast to step-by-step debugging, does only execute asingle thread at a time - the main or the current thread. It Cannot invoke new threads or tasks. Therefore your tool will stuck.
Background:
I have a C#.Net (.Net 4.0) Website that calls a engine to grab data from an external database through a vendor executable file that I cannot modify. Whenever user click on a specific button, the webpage will instruct the engine to spawn a few threads, and each thread will spawn a process of the executable (let's called it ABC.exe) to grab the data. The executable will then run, and save the data grabbed into a CSV file on the server. The threads then read the CSV first and consolidate all the data, do some calculation and return to the website.
Problem:
When we deployed the website to IIS 7.5 on a web server (running Window 7, four virtual processors), if we spawn more than 4 threads, the processes will just stuck there.
Test done:
When we run the exact codes using Visual Studio on the same server, no error occurred. All the threads are spawned correctly, and all process is running correctly. This is very weird.
When two user click on the button and both click will spawn 4 threads, the first four threads will work correctly while the second four threads will just stuck there.
When we run the thread with different executables that do not perform any connections, the code works.
In our code, using Task or Thread doesn't make a difference.
We suspect that this might have something to do with the outbound connections allowed to a specific IP in IIS.
Can anyone shed some light on this? Let me know if any further information is required. Thanks!
A couple of thoughts:
Could this be tied to thread pool threads? The CLR tries to prevent the CPU from unnecessary spinning by not handing out (initially anyways) more threads on the thread pool thread than there are processors present. Are there 4 virtual processors present? Thread pool threads should resume eventually, though, so make sure that your threads are really stuck, and not running serial.
I know of a deadlock condition when redirecting standard output in C#. Double check the MSDN article to make sure this is not happening to you.
Additional thoughts:
At this point, it sounds like your ABC.exe is suspect. Since you have Visual Studio on the server, I recommend that you fire up a separate instance of Visual Studio, and attach to one of the ABC.exe processes to see where it is hanging. Also try to run something that you are reasonably sure would exit, e.g. cmd /c dir instead of your ABC.exe.
Edit: 5/29:
I find it hard to believe that IIS would restrict outbound connections this way. Try the following simple downloaded instead of ABC.exe:
class Program
{
public static void Main(string[] args)
{
using (var reader = new System.IO.StreamReader(
System.Net.HttpWebRequest.Create("http://www.google.com")
.GetResponse().GetResponseStream()))
{
System.Console.WriteLine(reader.ReadToEnd());
}
}
}
I am developing an application level VSTO 4 Addin for Microsoft Excel 2007 / 2010.
The result is a windows forms based DLL using .Net 4 Client Profile.
Now I have to use a legacy COM-DLL. It is no problem to set the reference and access the COM-Methods via COM-Interop from .Net.
But the the (synchronous) method I need to call can take a minute or longer to get back.
I know your answer:
Use a worker thread...
I have used The Task Parallel Library to put the long lasting operation in a worker task and keep the GUI (Excel) responding.
But: The inprocess COM-Call (in the worker task/thread) still seems to block my GUI-Thread.
Why? Is it because Excel is always running as STA (Single Thread
Apartment)?
How can I keep the Excel GUI responding?
Is there a way to make it really asynchronous?
Thanks for any answers,
Jörg
Finally, I've found an answer to this topic:
I've readed a lot about COM Threading Models and then spoke to the developer of the COM-DLL I am calling as an InProc-Server.
Together we changed the threading model of the COM-DLL:
OLD (blocking): Single-Threaded Apartment (STA), (ThreadingModel=Apartment)
NEW (working): Multi-Threaded Apartment (MTA), (ThreadingModel=Free)
Since we have our own synchronization mechanisms in the COM-DLL, there are no problems caused by the missing synchronization via the standard Windows message queue.
Problem was, that even the UI Thread was idle and even if it did DoEvents, the important windows messages (WM_Paint, etc.) were not delivered.
Now they are. The UI is responding at every time and the call to the COM-DLL is still done in a worker thread (as mentioned above, it's a ThreadPool thread which is used by the Task Parallel Library).
I have client and server threads in my applications. When I run these apps as standalone apps, these threads communicate properly.
But when I run client as JUnit and server as standalone, client thread dies within few seconds.
I couldn't get, why such different behavior.
When the JUnit runner terminates, all spawned threads etc. are killed too (as it is most likely run in a separate JVM instance).
Here is a (rather old) article describing the problem you experienced (the GroboUtils library it is recommending seems to have been abandoned long time ago though). And another, recent one, with a more modern solution using the new Java concurrency framework.
The gist of the latter solution is that it runs the threads via an executor, which publishes the results of the runs via Futures. And Future.get is blocking until the thread finishes with the task, automatically keeping the JUnit tests alive. You may be able to adapt this trick to your case.
I'm currently working on a solution that has two projects, a console and a form application. The console application is the main entry point to my application, and from the console the user would run the form application.
The problem is, when the user boots the form application the rest of the business logic (from the console app) won't run until the form is closed. My first thought was to use a background worker for the form, but the business logic in the form project already uses a background worker (and I only have two CPUs...). Perhaps this could be my ignorance for multithreading, but is there a way to do this?
Any thoughts are much appreciated!
Cheers
Well, this is pretty unusual. In general, it doesn't make a lot of sense to provide the user with a nice GUI and still leave a console window up and interactive.
But yes, calling Application.Run() or Form.ShowDialog() is going to block the thread. It has to, the message loop needs to be running to keep the GUI alive. If you do this, be sure to put the [STAThread] attribute on the Main() method.
The only other decent alternative is to start a thread. This isn't a problem, a UI thread doesn't burn any CPU cycles. Code only ever runs when the user does something, it's otherwise idle 99% of the time. Be sure to call the thread's SetApartmentState() method before you start it, STA is required.