How to make code in COM control yield to other processes? - c#

I am using an old COM component (communications class library) in a new C# application. The COM control handles communication with some of our instruments. One of the functions is to download data, which, depending on the size of data, can be a rather lengthy operation. The new C# app is set up to handle the downloading as a thread. The problem is, when the code is executing the download function, everything else freezes up, so I cannot click a 'Cancel' button in the UI. I've added a Sleep () (trying everything from 0 to 1000 as params) call to the download code after every block without success. The part that has me confused is if my download thread, instead of calling into the COM control, simply executes an infinite loop in C#, I can cancel out of that because the UI is active. Does anyone have any thought on what I can try to make the download thread yield?
Thanks

If the threading model of the COM component is STA and you are creating it in the main UI thread and then calling the method to download data from a secondary thread the call will be marshaled and executed back on the UI thread and basically blocking your application.
STA COM components require to be created in a STA thread that pumps messages because all calls to the component will be marshaled and executed in the thread that created it independently of the thread that actually calls a method on the COM component.

Related

How to call code to be run on specific worker thread from Windows Phone 8 UI thread?

My application is derived from a Windows Phone 8 Direct3D Xaml sample, where a C# program instantiates a WinPRT component that contains a Direct3D device. The C# code runs on the UI thread and the component code runs on a separate application thread. The WinPRT component works with a C++ pre-compiled library that contains variables declared per-thread, static __declspec(thread).
The variables get initialized when needed in the application thread, but the shutdown (caused by the lifecycle Closing event) is called on the UI thread. The shutdown process uses the wrong set of per-thread variables which haven't been initialized and causes a crash.
I haven't found any method on the WinPRT component that gets called on the application thread during shutdown. I was hoping to find one to hook my stuff into but there doesn't seem to be any.
So, how do I call the shutdown code to be run on the application thread from the UI thread?
WinPRT severely limits the threading functionality available to me. I haven't been able to find a workable solution. I looked at the Dispatcher class, but on WinPRT it's only used to run code on the UI thread from a worker thread and not vice versa. What other options might there be?

How to make 2 forms on 2 separate threads in C# winform application

I am developing an interface in my C# 4.0 winform application, to fire some sms in bulk. Each message content is different so that I have to fire messages one by one. I have a form from where the end user can shoot smss, it may be more than a thousand.
I want to manage a queue. If the user shoots a sms then it will be submitted to the queue and the queue will send sms one by one.
So I have to create a form to manage the queue. The problem is that I want my application to work normally and in the background the queue sends sms.
So how can I achieve this task? I have tried BackGroundWorker, but I don't know how to maintain a separate thread with a form.
All forms must be on the UI thread. The sending of the SMS should be performed by the BackgroundWorker.DoWork event. The updating of the form is then done by BackgroundWorker.RunWorkerCompleted event.
The UI thread is main thread of the application for SWF (winforms)
If you are using C# 4.0 or above, you may also want to investiage the Take Parallel Library (http://msdn.microsoft.com/en-us/library/dd460717.aspx). But I would first get BackgroundWorker implementation to work. Then use TPL to send simultaneous SMS. Could really speed things up.
you have to create one thread (called worker thread) which runs for the life your application.
you have to have a queue or even better a concurrent queue http://msdn.microsoft.com/en-us/library/dd267265.aspx
the worker thread wait when an item (sms) appears in the queue, takes that item and do its work.
the UI is completely decoupled from that work.
this is most basic use of the class Thread.
Background worker is least suitable solution. obviously you can use a washing machines to build a house but most people use bricks.
You can start Thread then create new instance of form on it (with no parent) and then start message loop (such code located in Main method of project's template).
Remember, any form (generally any GDI object) can be used only on thread that creates it. E.g you can't create child form on another thread, then parent's. Every GUI thread must run message loop.

Why is FileUtilities.CopyFile wrapper for CopyFileEx interfering with winforms?

I’m using the FileUtilities.CopyFile wrapper for CopyFileEx from here http://msdn.microsoft.com/en-us/magazine/cc163851.aspx . I thought the CopyFileCallbackAction doesn’t get called until after the file is copied (I’ve tried copying a large file). And therefore asked this How do I get CopyFileEx to report back so I can cancel a file copy operation? question. But now I’ve found that it actually gets called many times, but for some reason it messes the form on which I’m trying to show the progress – the form doesn’t get updated until the copy is done. In fact, if I try running it in the Shown event handler – the form has empty boxes where buttons are supposed to be – until the copy is done. Why is that?
You will need to call CopyFileEx from a background thread. At the moment the call to CopyFileEx is blocking the UI thread. That's why the UI does not update.
The callback action is indeed called repeatedly. This is so that you can report to the user the progress of a long running file operation.
Just to be clear, this is what happens when you call CopyFileEx:
Enter CopyFileEx
Start copying
Call your callback
Continue copying
Call your callback
....
Return from CopyFileEx
For the entire duration of the file copy, the executing thread is busy copying the file rather than pumping the message queue. Although this is WinForms and not Win32, WinForms is a relatively lightweight wrapper around the standard Win32 GUI framework. Your message queue needs to be serviced regularly and so all long running tasks need to be run away from the UI thread.
One final point: remember that when you get your progress callback, you need to use Invoke or BeginInvoke when updating any UI. This is because code that updates UI needs to be run from the UI thread.

Background worker issue

i have a class which, when a certain part of the gui is clicked will
-create a backgroundworker and do the following taks
-create a new object(this is a new windows form)
-call a method on it which gets some data
-populate the new windows form gui with that data
The problem is there is a gui component on the form which cant be created from outside of the main programme thread, if i do try i get the error
Active x .... cannot be instantiated because the
current thread is not in a
single-threaded apartment.
is there help people can offer so i can structure this?
in my do work
Don't create GUI components in a background thread. Use the background thread to get and process data, then render them in the UI in the main thread. I know that this in inconvenient, because
creating lots of UI elements can also take a lot of time and
creating them in the UI thread requires you to split your code into UI part and data processing part,
but there's not really a way around it. .NET UI components are not designed to be handled in background threads.
To perform only certain operations of your code in the main thread, you can use
someUIControl.Invoke(...) (WinForms) or
Dispatcher.Invoke(...) (WPF)
in the DoWork event handler of your BackgroundWorker. Alternatively, you can perform the UI operations in the RunWorkerCompleted event handler of your BackgroundWorker, which always executes in the UI thread.
The UI should only be managed by the UI thread.
One possible solution would be to load the data asynchronously with the BackgroundWorker, and when it is done use the Result property of the DoWorkEventArgs to pass the results back to the UI thread and then display the new form.

Open InternetExplorer COM object to do some automation using Wating from WPF app, but keep UI responsive. is this possible?

I have an app that runs a process which needs to open an internet explorer, go to an url, and do some stuff there, input some data, and return.
This usually takes a while (several pages that need to be filled, doesn't matter). The problem is, while this process is being done, the calling app (a standard wpf app) UI is unresponsive/frozen. When the process returns, i have some info that i need to set in one of the WPF app's objects
The main problem is that since IE needs to be called from within an STA thread, if I try to call it from within the dispatcher asynchronously or synchronously, for some reason the UI is blocked (i have tried with different DispatcherPriority-es but didn't get lucky).
If i start a new BackgroundWorker, that thread is in MTA mode (and i can't switch it back), so there's a problem and i have an exception
I'm really lost here, could anyone put some light into this? maybe what i want to do is simply not possible.
Have you tried creating your own background thread (not relying on BackgroundWorker), and set its ApartmentState to STA?

Categories

Resources