Hiya
In my framework I have 2 threads:
- Test Case Thread
- BackgroundWorker thread
The background worker component never uses Ranorex function, but uses windows API instead.
In the Main() function ive put [STAThread]
However In the ranorex log i get:
"The apartment state of the current thread is not set to STA. Please make sure that all threads accessing Ranorex methods have their apartment state set to STA."
And some Ranorex method cause a crash.
Can you advise please
Thanks
STA threading
Re: STA threading
actually the problem comes from our AUT
The Spy Tool crashes when pointed at a certain window
Can I raise a support issue for this?
The Spy Tool crashes when pointed at a certain window
Can I raise a support issue for this?
- Support Team
- Site Admin
- Posts: 12145
- Joined: Fri Jul 07, 2006 4:30 pm
- Location: Houston, Texas, USA
- Contact:
Re: STA threading
Thank you for reporting this issue to support_at_ranorex.com!atom wrote:Can I raise a support issue for this?
If someone else experiences a similar problem with Ranorex Spy, please contact support_at_ranorex.com and if possible provide a sample application that we can reproduce the crash with!
Regards,
Alex
Ranorex Support Team
Re: STA threading
Hi,
I am using Ranorex 2.1.2 version.
I am also getting same warning
“The apartment state of the current thread is not set to STA. Please make sure that all threads accessing Ranorex methods have their apartment state set to STA.”
in my Ranorex logs. But I am able to execute one test case now. But if I need to executes 200+ test cases in future.
What will be the impact of this issue?
Thanks
I am using Ranorex 2.1.2 version.
I am also getting same warning
“The apartment state of the current thread is not set to STA. Please make sure that all threads accessing Ranorex methods have their apartment state set to STA.”
in my Ranorex logs. But I am able to execute one test case now. But if I need to executes 200+ test cases in future.
What will be the impact of this issue?
Thanks
Re: STA threading
Depends what your other thread is doing... does it use any Ranorex methods?
- Support Team
- Site Admin
- Posts: 12145
- Joined: Fri Jul 07, 2006 4:30 pm
- Location: Houston, Texas, USA
- Contact:
Re: STA threading
All threads using the Ranorex framework need to have a Single Threaded Apartment (STA) state. For new threads started in your application you need to call the Thread.SetApartmentState method, for the main thread of your automating process you have to apply the STAThreadAttribute to the Main method of your .NET application. If you do not set the apartment state to STA, web testing won't work at all and some attributes of other technologies (MSAA, WPF) won't be accessible.
Ranorex only checks the apartment state of the thread that initializes the Ranorex framework. So, you will get this warning only if the thread first accessing Ranorex classes does not have the STA apartment state.
Regards,
Alex
Ranorex Support Team
Ranorex only checks the apartment state of the thread that initializes the Ranorex framework. So, you will get this warning only if the thread first accessing Ranorex classes does not have the STA apartment state.
Regards,
Alex
Ranorex Support Team
-
- Posts: 13
- Joined: Thu Apr 15, 2010 4:34 pm
Re: STA threading
Hi
I seem to be having the same problem.
I dumbed down my application to a bare bones program (code below). I have a simple windows form with a single text box and a button.
I have a separate thread that I start which executes in a loop looking for a particular windows form (alert). When it finds the form it reads info from it and sends the info back to controls on my application form.
I am using the background worker method to update my controls via the ProgressChanged as recommended by microsoft.
I keep getting the warning:
"
The apartment state of the current thread is not set to STA. Please make sure that all threads accessing Ranorex methods have their apartment state set to STA.
"
Here is my code in the form (it has a text box called 'txtScanCount' and a button called 'BtnStartScan'). Appreciate any help:
Regards,
Mark
// Listing for MainForm.cs
using System;
using System.Collections.Generic;
using System.Drawing;
using WinForms = System.Windows.Forms;
using System.ComponentModel;
using Ranorex;
namespace MyProj
{
/// <summary>
/// Description of MainForm.
/// </summary>
public partial class MainForm : System.Windows.Forms.Form
{
static System.ComponentModel.BackgroundWorker bw;
public MainForm()
{
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
}
//[STAThread]
void BtnStartScanClick(object sender, EventArgs e)
{
bw = new BackgroundWorker();
bw.WorkerReportsProgress = true;
bw.DoWork += bw_DoWork;
bw.ProgressChanged += bw_ProgressChanged;
bw.RunWorkerAsync (); // Start Scan();
}
//[STAThread]
void bw_ProgressChanged (object sender, ProgressChangedEventArgs e)
{
txtScanCount.Text = e.ProgressPercentage.ToString();
System.Threading.Thread.Sleep(50);
if (e.UserState!=null)
{
//Various operations on the userstate object
}
}
[STAThread]
void bw_DoWork(object sender, DoWorkEventArgs e) // Scan for alerts
{
int scanCount=0;
while (true)
{
// Send scanCount back to main form
bw.ReportProgress (scanCount); // Send scan count to form
try
{
Ranorex.Form frmAlert=Host.Local.FindSingle("/form[@title='Alert activated']",1000);
Report.Info("Scan(); Alert Window Detected." );
// Here we get some info from the Alert window and close it
string formInfo="";
bw.ReportProgress (scanCount, formInfo);
}
catch (Ranorex.ElementNotFoundException e1)
{}// Continue to next scan if form not found
if (scanCount==10) // break out of loop after 10 scans
break;
scanCount++;
}
} //End function doWork
}
}
I seem to be having the same problem.
I dumbed down my application to a bare bones program (code below). I have a simple windows form with a single text box and a button.
I have a separate thread that I start which executes in a loop looking for a particular windows form (alert). When it finds the form it reads info from it and sends the info back to controls on my application form.
I am using the background worker method to update my controls via the ProgressChanged as recommended by microsoft.
I keep getting the warning:
"
The apartment state of the current thread is not set to STA. Please make sure that all threads accessing Ranorex methods have their apartment state set to STA.
"
Here is my code in the form (it has a text box called 'txtScanCount' and a button called 'BtnStartScan'). Appreciate any help:
Regards,
Mark
// Listing for MainForm.cs
using System;
using System.Collections.Generic;
using System.Drawing;
using WinForms = System.Windows.Forms;
using System.ComponentModel;
using Ranorex;
namespace MyProj
{
/// <summary>
/// Description of MainForm.
/// </summary>
public partial class MainForm : System.Windows.Forms.Form
{
static System.ComponentModel.BackgroundWorker bw;
public MainForm()
{
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
}
//[STAThread]
void BtnStartScanClick(object sender, EventArgs e)
{
bw = new BackgroundWorker();
bw.WorkerReportsProgress = true;
bw.DoWork += bw_DoWork;
bw.ProgressChanged += bw_ProgressChanged;
bw.RunWorkerAsync (); // Start Scan();
}
//[STAThread]
void bw_ProgressChanged (object sender, ProgressChangedEventArgs e)
{
txtScanCount.Text = e.ProgressPercentage.ToString();
System.Threading.Thread.Sleep(50);
if (e.UserState!=null)
{
//Various operations on the userstate object
}
}
[STAThread]
void bw_DoWork(object sender, DoWorkEventArgs e) // Scan for alerts
{
int scanCount=0;
while (true)
{
// Send scanCount back to main form
bw.ReportProgress (scanCount); // Send scan count to form
try
{
Ranorex.Form frmAlert=Host.Local.FindSingle("/form[@title='Alert activated']",1000);
Report.Info("Scan(); Alert Window Detected." );
// Here we get some info from the Alert window and close it
string formInfo="";
bw.ReportProgress (scanCount, formInfo);
}
catch (Ranorex.ElementNotFoundException e1)
{}// Continue to next scan if form not found
if (scanCount==10) // break out of loop after 10 scans
break;
scanCount++;
}
} //End function doWork
}
}
-
- Posts: 13
- Joined: Thu Apr 15, 2010 4:34 pm
Re: STA threading
Hi,
I seem to have resolved my STA Threading problem by relocating the Ranorex "FindSingle" function into the ProgressChanged method. In other words, I've put the Form search function into the GUI thread instead of the background worker thread.
It seems as if we cant have the GUI interactive functions within the background worker.
My background worker method now simply has a sleep for 3 seconds, and then it sends a message via the ReportProgress event to the ProgressChanged method (on the GUI thread) which calls the FindSingle function.
While the background working is sleeping, I generally have access to my GUI window. It only locks for the short moment of time that the process is running FindSingle. The behaviour is pretty much as I want.
Interested to know if there are any opinions on this solution.
My CSharp code is given below.
Regards,
Mark
// CSharp Listing
using System;
using System.Collections.Generic;
using System.Drawing;
using WinForms = System.Windows.Forms;
using System.ComponentModel;
using Ranorex;
namespace MyProj
{
/// <summary>
/// Description of MainForm.
/// </summary>
public partial class MainForm : System.Windows.Forms.Form
{
static System.ComponentModel.BackgroundWorker bw;
public MainForm()
{
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
}
void BtnStartScanClick(object sender, EventArgs e)
{
bw = new BackgroundWorker();
bw.WorkerReportsProgress = true;
bw.DoWork += bw_DoWork;
bw.ProgressChanged += bw_ProgressChanged;
bw.RunWorkerAsync (); // Start Scan();
}
void bw_ProgressChanged (object sender, ProgressChangedEventArgs e)
{
txtScanCount.Text = e.ProgressPercentage.ToString();
try
{
Report.Info("Scan(); Searching for Alert Window: " + e.ProgressPercentage.ToString() );
Ranorex.Form frmAlert=Host.Local.FindSingle("/form[@title='Alert activated']");
// Here we get some info from the Alert window and close it
}
catch (Ranorex.ElementNotFoundException e1)
{}// Continue to next scan if form not found
if (e.UserState!=null)
{
//Various operations on the userstate object
}
}
void bw_DoWork(object sender, DoWorkEventArgs e) // Scan for alerts
{
int scanCount=1;
while (true)
{
// Send scanCount back to main form
bw.ReportProgress (scanCount); // Send scan count to form
System.Threading.Thread.Sleep(3000);
if (scanCount==2) // break out of loop after 10 scans
break;
scanCount++;
}
} //End function doWork
}
}
I seem to have resolved my STA Threading problem by relocating the Ranorex "FindSingle" function into the ProgressChanged method. In other words, I've put the Form search function into the GUI thread instead of the background worker thread.
It seems as if we cant have the GUI interactive functions within the background worker.
My background worker method now simply has a sleep for 3 seconds, and then it sends a message via the ReportProgress event to the ProgressChanged method (on the GUI thread) which calls the FindSingle function.
While the background working is sleeping, I generally have access to my GUI window. It only locks for the short moment of time that the process is running FindSingle. The behaviour is pretty much as I want.
Interested to know if there are any opinions on this solution.
My CSharp code is given below.
Regards,
Mark
// CSharp Listing
using System;
using System.Collections.Generic;
using System.Drawing;
using WinForms = System.Windows.Forms;
using System.ComponentModel;
using Ranorex;
namespace MyProj
{
/// <summary>
/// Description of MainForm.
/// </summary>
public partial class MainForm : System.Windows.Forms.Form
{
static System.ComponentModel.BackgroundWorker bw;
public MainForm()
{
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
}
void BtnStartScanClick(object sender, EventArgs e)
{
bw = new BackgroundWorker();
bw.WorkerReportsProgress = true;
bw.DoWork += bw_DoWork;
bw.ProgressChanged += bw_ProgressChanged;
bw.RunWorkerAsync (); // Start Scan();
}
void bw_ProgressChanged (object sender, ProgressChangedEventArgs e)
{
txtScanCount.Text = e.ProgressPercentage.ToString();
try
{
Report.Info("Scan(); Searching for Alert Window: " + e.ProgressPercentage.ToString() );
Ranorex.Form frmAlert=Host.Local.FindSingle("/form[@title='Alert activated']");
// Here we get some info from the Alert window and close it
}
catch (Ranorex.ElementNotFoundException e1)
{}// Continue to next scan if form not found
if (e.UserState!=null)
{
//Various operations on the userstate object
}
}
void bw_DoWork(object sender, DoWorkEventArgs e) // Scan for alerts
{
int scanCount=1;
while (true)
{
// Send scanCount back to main form
bw.ReportProgress (scanCount); // Send scan count to form
System.Threading.Thread.Sleep(3000);
if (scanCount==2) // break out of loop after 10 scans
break;
scanCount++;
}
} //End function doWork
}
}
- Support Team
- Site Admin
- Posts: 12145
- Joined: Fri Jul 07, 2006 4:30 pm
- Location: Houston, Texas, USA
- Contact:
Re: STA threading
GUI threads always have a Single Threaded Apartment (STA) state (Windows Forms require STA threads). It looks like the BackgroundWorker thread is not STA, but all the event handlers are invoked on the main GUI thread. If you're doing the actual work on the ProgressChanged event, you could even use a simple System.Windows.Forms.Timer component instead.markvanraalte wrote:In other words, I've put the Form search function into the GUI thread instead of the background worker thread.
I don't think you can setup the BackgroundWorker thread to use STA model, since the BackgroundWorker uses the .NET ThreadPool. You could use a simple Thread instead of the BackgroundWorker and set the apartment state of that thread to STA. Note, though, that whenever you try to access the GUI from that newly created thread you need to invoke the call on the GUI thread, e.g. by invoking Control.Invoke on the main thread. See following websites for more info:
http://www.albahari.com/threading/part3 ... nd_Windows
http://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx
Regards,
Alex
Ranorex Support Team
-
- Posts: 13
- Joined: Thu Apr 15, 2010 4:34 pm
Re: STA threading
Thanks Alex
This is really helpful. Now I understand why I cant use the background worker with the STA model.
Also, as you point out I only need a simple timer for my purpose, so I think I'll re write my module using a timer.
Regards,
Mark
This is really helpful. Now I understand why I cant use the background worker with the STA model.
Also, as you point out I only need a simple timer for my purpose, so I think I'll re write my module using a timer.
Regards,
Mark