void itemCommand_Click(Office.CommandBarButton Ctrl, ref bool CancelDefault)
{
var thread = new Thread(() =>
{
if (LoginCheck())
{
ItemWindow itw = new ItemWindow();
//Dispatcher.CurrentDispatcher.Invoke((System.Action)(() =>
//{
itw.Show();
itw.Closed += (sender2, e2) => { itw.Dispatcher.InvokeShutdown(); };
//}));
Dispatcher.Run();
}
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
I keep getting error message of "The calling thread cannot access this object because a different thread owns it." on line "itw.show();" when this function called twice. It works fine for the first call, and after the window is closed and trying to open again, it fails. As I commented out "Invoke" method, it doesn't work with Dispatcher either. Please help me to find the solution. Thank you.
----------------- Edit
The reason why I'm creating a new thread is because it is an Excel addin. I can't create windows from main thread which is the excel that collides with windows if i create them from main thread.
The thing I don't understand is that why does the new instance(ItemWindow) from new thread collide with old thread.
I created a simple test method in a new application that is called when I click the (only) button on my main form. The method looks like this:
Window1
is a window class I made that has nothing but a singleTextBlock
on it. I can click that button as many times as I want, and it continues to open new windows with no issues (regardless whether or not I close the previous one first).I suspect the issue is occurring in code that you are not showing us somewhere. You need to be very careful that nothing on your new thread attempts to access anything UI related from your main thread. Windows running on separate threads cannot communicate with each other unless they go through the dispatcher of the other thread. The exception you are seeing is thrown when any method or property of a DispatcherObject is accessed from a thread other than the one that created the object.
Taking a step back, why is it important that the new window be on its own thread? Unless the new window is going to monopolize the thread, it will probably run fine on the main thread. If you are running some long blocking operation, perhaps that operation alone should be moved to a thread rather than the entire window. I don't know what you are doing exactly, but it is something to think about.
EDIT: Realizing that you may not be running in a typical WPF application (looks like you might be in an Office plugin), I updated my test to launch the windows completely standalone on their own threads. However, I am still able to launch two windows in a row with no issues.
Here is my new test. This method and the test class
Window1
are the entirety of my application.So, there appears to be nothing inherently wrong with what you are trying to do, nor do I see any obvious issue in your code. I suspect that there is some invalid cross-thread communication happening somewhere in your custom window while it is being shown. (Either that, or you are running into an issue specific to Office plugins.)