So this is an odd one. I have a simple form to do testing on other code. It used to work, but after adding some Fakes assemblies (trying to automate data generation for unit tests), my code halts with a ThreadStateException
on ShowDialog
. No multi-threading on my part, didn't even make it to any non-boiler plate code. Searching is not helpful, as the only solution is supposed to be marking with the STAThread
attribute which is already done. And again, the code used to work fine, no changes in project configuration other than the Fakes.
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
Exception happens on ShowDialog
below.
private void button1_Click(object sender, EventArgs e)
{
using(var fod = new OpenFileDialog())
{
if(fod.ShowDialog()==System.Windows.Forms.DialogResult.OK)
{
runTest(fod.FileName );
}
}
}
Edit:
I added a breakpoint in Main
to check System.Threading.Thread.CurrentThread.GetApartmentState()
, and it is returning MTA, so it appears the STAThread
attribute is being ignored. I don't think you can change the apartment of a running thread, so I'm at a loss.
I fixed it, it was a fairly dumb project configuration mistake.
I had a project reference to another test project (for the data I needed to populate). For system configuration reasons I'd rather not go into, both of these projects had the same Assembly name. I found this out as I tried to work around issue by creating my own app thread, and then ran into other type load exceptions. I moved the classes around so the assemblies don't have to reference each other.
I have no idea why that caused the main thread to be created as MTA, but it did. Any insight would be appreciated.
For completeness, this was the workaround I didn't need,
var runapp = new System.Threading.ThreadStart(() =>
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
});
var thread = new System.Threading.Thread(runapp);
thread.SetApartmentState(System.Threading.ApartmentState.STA);
thread.Start();
thread.Join();