I have a thread, called TAlertThread. The thread interacts with its owner by triggering events. For example, when certain data is available inside the thread, it sets some temp variables and calls Synchronize(UpdateAlert) which in turn triggers the appropriate event.
Now the thread works perfectly in any standard windows application. My problem is when I put that thread inside of an ActiveX form (TActiveForm). The ActiveX control (aka COM object) is then embedded inside of a Windows Desktop Gadget (via HTML / Javascript). I also have experience with this, the gadget is not the issue. The ActiveX component works fine in its destination, except the thread is never executed. It's even being called EXACTLY the same way as I called it from the App.
Is this some limitation with ActiveX, blocking threads from executing? I wouldn't think so, because other things that require threads internally (such as TADOConnection) work. I am in fact properly calling CoInitialize and CoUninitialize appropriately. Again, works perfect in an application, but does not work at all in ActiveX.
Here is how I call this thread...
procedure TRMPDashXS.ExecThread;
begin
//Thread created suspended
lblStatus.Caption:= 'Executing Thread...';
fThread:= TAlertThread.Create(fConnStr); //fConnStr = connection string
fThread.Priority:= tpIdle;
fThread.OnConnect:= Self.ThreadConnected;
fThread.OnDisconnect:= Self.ThreadDisconnected;
fThread.OnBegin:= Self.ThreadStarted;
fThread.OnFinish:= Self.ThreadFinished;
fThread.OnAlert:= Self.ThreadAlert;
fThread.OnAmount:= Self.ThreadAmount;
fThread.Resume; //Execute the thread
end;
I suspect this might describe exactly what you're experiencing in your version of Delphi:
http://soft-haus.com/blog/2009/02/10/codegear-borland-activex-threading-synchronization-problems/
which references the same article you cited:
http://edn.embarcadero.com/article/32756
I'm not sure if that helps ... but I hope it does. At least a little :)
PS:
Is there any particular reason you have to use Com/ActiveX and/or TActiveForm?
According to this article here: http://edn.embarcadero.com/article/32756 web browsers don't allow threading via ActiveX. However that still doesn't explain why it doesn't work when I put it in a C# application.
Related
we have an issue in MFC-based application related to “current MFC state” and threads. In main thread we call VisualManager, because we want to have fancy toolbars. The call ends up in CMFCVisualManagerOffice2007::OnUpdateSystemColors function located inside afxvisualmanageroffice2007.cpp, which changes “current resource handle” by calling AfxSetResourceHandle function. This function gets “current module state” and changes “current resource handle” from MyApp.exe to mfc140u.dll. This is fine, because assets for VisualManager are located in that DLL and the change will be restored back to MyApp.exe in all cases.
However, what is not fine is that we spawn a new thread just before call to VisualManager (by using AfxBeginThread), this thread needs to load some strings from string table (by using CString class), but it sometimes fails to do so. It fails because there is race with main thread about AFX_MODULE_STATE::m_hCurrentResourceHandle variable. The thread expect it to be set to MyApp.exe, but the main thread changes it to mfc140u.dll and back, the “current resource handle” is effectively a global variable.
So, my questions are: 1) Are we doing something obviously wrong managing our MFC-based threads? Should we somehow copy or protect the “module state” so our new thread is immune to the change main thread is doing? Should aim MFC to create something like per-thread variable / state? 2) I believe Microsoft is wrong here, changing what is effectively a global variable and screwing other threads expectations, VisualManager should obtain the handle and pass it to all its functions as a parameter. Am I right?
EDIT:
Hi guys #iinspectable, #cha, I have an update, sorry it took so long. Steps to reproduce: Open Visual Studio 2015 Update 3, Create new MFC application through the wizard, make sure it has the "Project style" and "Visual style and colors" selected as "Office" and "Office 2007 (Blue theme)". Open file afxvisualmanageroffice2007.cpp from MSVS folder and put 4 break-points into CMFCVisualManagerOffice2007::OnUpdateSystemColors function where it calls AfxSetResourceHandle. Open file MFCApplication1.cpp in your newly created project folder and put this code [1] into CMFCApplication4App::InitInstance function just before CMainFrame* pMainFrame = new CMainFrame;, put break-point into this thread proc.
Now build and run this MFC application in debug mode, on each break-point hit, use freeze thread and thaw thread functions from Threads window, so you will arrange main thread in the middle of CMFCVisualManagerOffice2007::OnUpdateSystemColors function just after setting the global variable using AfxSetResourceHandle function and the worker thread before CStringT::LoadString. Now the load string will fail because it is looking for it inside mfc140ud.dll instead of using resource chain and MFCApplication1.exe.
I believe this is Microsoft's bug (changing global variable for a while), my code-base is full of innocent CString::LoadString calls which rely on carefully and correctly constructed resource chain with various plug-in DLLs and with an .exe at the end. If this is not Microsoft's bug then it is my bug relying on MFC on providing me a usable resource chain. I would need to create my own resource-chain-like functionality and use it everywhere when loading strings and other stuff from resources.
// [1]
AFX_THREADPROC thread_proc = [](LPVOID pParam){
CString str;
str.LoadString(IDS_CAPTION_TEXT);
UINT ret = 0;
return ret;
};
::AfxBeginThread(thread_proc, (LPVOID)nullptr);
// Same result with ::AfxBeginThread(CRuntimeClass*) overload.
Is it possible to print in Silverlight without blocking the UI thread?
I have to print a lot of pages, and consequently my UI freezes for a while. I would like to print on a background thread instead (and update a progress bar if possible), but can't figure out how.
I tried calling the Print() method of my PrintDocument inside the DoWork() method of a BackgroundWorker, but that gives me an UnauthorizedAccessException "Invalid cross-thread access".
It seems that even initiating a PrintDocument is not possible outside the UI thread:
PrintDocument pd = new PrintDocument(); in BackgroundWorker.DoWork() throws the same exception.
I found a lot of posts where people say that printing has to happen on the UI thread, but no documentation of this. I'm new to multithreading, so any pointers in the right direction would be appreciated.
I had this problem and came across this question which unfortunately didn't have the answer i was hoping for. But I thought that for anyone else who comes across this problem, this may at least shed some light.
I was following this article on printing in Silverlight, It works like a charm for regular printing on the UI Thread, but for actually trying to print on a separate thread I don't think it's possible. I switched out the last line of code in the example
printDocument.Print("SLPrintDemo document");
with an alternate one to see if it would work
new Thread(() => printDocument.Print("SLPrintDemo document")).Start();
To see if the print job itself would spawn in a separate thread. However though the code compiles and runs fine, the document does not print. The reason seems to be that once the Print command is fired, it then fires up the printing options dialog for choosing printer and other options etc. At this point it is no longer on the UI thread so nothing happens ( No exceptions, so i'm assuming they're swallowed somewhere)
So as far as I can tell at the moment, there is no way to print in Silverlight that is not in the UI thread.
Use Dispatcher for updating your UI. For example:
Dispatcher.BeginInvoke(() =>
{
ProgressBar.Value = 100;
});
I am developing a Windows forms application which connects to a piece of hardware, acquires a lot of data (~1 GSample/sec), processes it, and spits it out to the screen upon a button click. I am now trying to automate the process in a loop that can be started/stopped at any time so I can monitor it whilst tweaking the input to the acquisition hardware. I thinks it's clear that I need to do this on a separate thread, but I'm having a heck of a time trying to do this in c++/cli - I have found a number of good examples using MFC, which is not supported by Express.
Specifically: My task is to press a button which is handled in Form1.h, to call a function in my main file Acquisition.cpp which contains the following code (currently an infinite loop)
void Form1::realTimeUpdate()
{
// live is a boolean variable set by a button on the form
while(live)
{
displayVariance(getVar(getQuadratures(100),nbrSamples));
}
}
I wish to execute this code in a separate thread so that the main program can listen for the user request to stop the operation. Without threading, I currently have to forcefully quit the program (or set it to run a fixed number of times) to stop it.
Is there any suggestions how I might go about running this code on a separate thread?
I've (unsuccessfully) tried a few things already:
Modifying the example given in This Microsoft Example. Problem: requires /clr:oldSyntax option which is incompatible with the other 1300 lines of code in the program.
Trying to do what I'd do in Java (Declare a global thread and start/stop it from any point in the code. Problem: Compiler won't let me declare a global System::Threading.Thread
this beautiful example. Problem: Requires MFC.
Any suggestions would be greatly appreciated!
You can use a BackgroundWorker or a Thread to handle this. You'll need to make sure that the portion of your work that updates the UI is marshaled back to the UI thread, however.
Here is a tutorial on threading in C++/CLI.
For the record, upon Reed's suggestion about using a BackgroundWorker, I sifted through the code at the bottom of this page and modified my code so that:
It created a new backgroundWorker BGWorker in which BGWorker->DoWork() called my realTimeUpdate() function.
A button on the main Form calls either RunWorkerAsync() or CancelAsync() depending on whether or not the process is running (checked by a boolean flag in my main program).
The realTimeUpdate() function is now passed a BackgroundWorker - realTimeUpdate(BackgroundWorker^ worker, DoWorkEventArgs ^ e) After each calculation is complete within the internal loop, it calls worker->ReportProgress(result) function. In the BGWorker->ProgressChanged() function a separate function, upDataUI(int) draws the result on the main form.
Thanks again for the help.
I have created psedo code of what I would like to achieve. Inside of the SomeBLL().PerformBeginWork() threads will be created and maintained to do work. Using dot.net 4.0, what would be the best way to put this processing into an non-UI thread and still allow the assigned delegates to fire and update the UI in both a windows and web application without code modifications?
public class SomeBLL : BaseAsynWorker, IAsyncWorker
{
...makes threads and does work (if events are assigned then call them)
}
On a web page
SomeBLL sm=new SomeBLL();
sm.OnBeginWork+=ProcessUIUpdate;
sm.OnProgressUpdate+=ProcessUIUpdate;
sm.OnEndWork+=ProcessUIUpdate;
sm.OnHardError+=ProcessHardError;
SomeThreadClass.Spawn(sm.PerformBeginWork())
In a non UI process
SomeBLL sm=new SomeBLL();
sm.PerformBeginWork();
You're looking for the SynchronizationContext class.
I'm beginning to wonder if this is impossible, but I thought I'd ask in case there's a clever way to get around the problems I'm having.
I have a Qt application that uses an ActiveX control. The control is held by a QAxWidget, and the QAxWidget itself is contained within another QWidget (I needed to add additional signals/slots to the widget, and I couldn't just subclass QAxWidget because the class doesn't permit that). When I need to interact with the ActiveX control, I call a method of the QWidget, which in turn calls the dynamicCall method of the QAxWidget in order to invoke the appropriate method of the ActiveX control. All of that is working fine.
However, one method of the ActiveX control takes several seconds to return. When I call this method, my entire GUI locks up for a few seconds until the method returns. This is undesirable. I'd like the ActiveX control to go off and do its processing by itself and come back to me when it's done without locking up the Qt GUI.
I've tried a few things without success:
Creating a new QThread and calling QAxWidget::dynamicCall from the new thread
Connecting a signal to the appropriate slot method of the QAxWidget and calling the method using signals/slots instead of using dynamicCall
Calling QAxWidget::dynamicCall using QtConcurrent::run
Nothing seems to affect the behavior. No matter how or where I use dynamicCall (or trigger the appropriate slot of the QAxWidget), the GUI locks until the ActiveX control completes its operation.
Is there any way to detach this ActiveX processing from the Qt GUI thread so that the GUI doesn't lock up while the ActiveX control is running a method? Is there something clever I can do with QAxBase or QAxObject to get my desired results?
After some experimentation, I was able to solve this by doing something I thought I'd tried earlier: creating a new QThread and calling QAxWidget::dynamicCall from the new thread. I must not have coded it correctly the first time I tried this solution; after sitting with a co-worker, we were able to get it to work. To be specific, what we did is:
(Step 1) Created a subclass of QThread to represent the thread I need to call dynamicCall().
(Step 2) In the constructor of my QThread, pass in a pointer to my original QAxWidget, and keep the pointer in a member variable.
MyThread::MyThread(QAxWidget* passedWidget) : QThread()
{
actualWidget = passedWidget;
}
(Step 3) In the run() method of the QThread, call the dynamicCall() method of the QAxWidget.
void MyThread::run()
{
QVariant result = actualWidget->dynamicCall(...parms as necessary...);
}
(Step 4) Back in my main code, when I need to execute dynamicCall(), I just call the start() method of MyThread. The start() method will execute run() in its own thread, thus sending the necessary command to the ActiveX object without blocking or stalling the main GUI thread.
If there is no event loop needed, then there is no need NOT to subclass QThread! I think this is the way to solve this without a bunch of signals to the main thread which (more than likely) owns the QAxWidget. The latest docs for Qt 5.3 referring to QThread also bears this out.