ShowDialog - Cross-thread operation not valid: Control'CheckAccountInfo' accessed from a thread othe

T

Tom C

I'm creating a Form in my component and setting it's parent to another
application mains window via ShowDialog(IWin32Window). If I set the
process name to say "Notepad" it works fine, and behaves as expected.
If I set the process name to my main application and do not run it
under VS 2005 is also works properly. Only when I'm debugging the
application does it throw the "Cross-thread operation not valid:
Control accessed from a thread other than the thread it was created
on."

I'm creating the showing the dialog from the same thread, so I don't
see why this error is occuring.

Thread uiThread2 = new Thread(UIThreadProc);
uiThread2.IsBackground = false;
uiThread2.Start(mySession);


private void UIThreadProc(Object mySession)
{

CheckAccountInfo oCheckingInfo = new CheckAccountInfo(mySession);

System.Diagnostics.Process[] procs =
System.Diagnostics.Process.GetProcessesByName("SomeApplication");
if (procs.Length != 0)
{
IntPtr hwnd = procs[0].MainWindowHandle;

// This line causes the mentioned exception while
running in the debugger
Result = oCheckingInfo.ShowDialog(new
WindowWrapper(hwnd));
}
}


public class WindowWrapper : System.Windows.Forms.IWin32Window
{
/// <summary>
///
/// </summary>
/// <param name="handle"></param>
public WindowWrapper(IntPtr handle)
{
_hwnd = handle;
}

public IntPtr Handle
{
get { return _hwnd; }
}

private IntPtr _hwnd;
}
 
N

Nicholas Paldino [.NET/C# MVP]

Tom,

Basically, what you are doing is wrong. This is not supported in any
way. The only way to get a window to appear as a child in another process
is to make a call into that process and have the process make the call, not
your process.

There's no way around it, and if your app eventually breaks in release
mode, you won't have a workaround.

You need to find some other way to do this (if it's possible).
 
T

Tom C

Tom,

    Basically, what you are doing is wrong.  This is not supported in any
way.  The only way to get a window to appear as a child in another process
is to make a call into that process and have the process make the call, not
your process.

    There's no way around it, and if your app eventually breaks in release
mode, you won't have a workaround.

    You need to find some other way to do this (if it's possible).

--
          - Nicholas Paldino [.NET/C# MVP]
          - (e-mail address removed)




I'm creating a Form in my component and setting it's parent to another
application mains window via ShowDialog(IWin32Window). If I set the
process name to say "Notepad" it works fine, and behaves as expected.
If I set the process name to my main application and do not run it
under VS 2005 is also works properly. Only when I'm debugging the
application does it throw the "Cross-thread operation not valid:
Control accessed from a thread other than the thread it was created
on."
I'm creating the showing the dialog from the same thread, so I don't
see why this error is occuring.
Thread uiThread2 = new Thread(UIThreadProc);
uiThread2.IsBackground = false;
uiThread2.Start(mySession);
private void UIThreadProc(Object mySession)
{
  CheckAccountInfo oCheckingInfo = new CheckAccountInfo(mySession);
  System.Diagnostics.Process[] procs =
System.Diagnostics.Process.GetProcessesByName("SomeApplication");
  if (procs.Length != 0)
  {
               IntPtr hwnd = procs[0].MainWindowHandle;
               // This line causes the mentioned exception while
running in the debugger
               Result = oCheckingInfo.ShowDialog(new
WindowWrapper(hwnd));
  }
}
   public class WindowWrapper : System.Windows.Forms.IWin32Window
   {
       /// <summary>
       ///
       /// </summary>
       /// <param name="handle"></param>
       public WindowWrapper(IntPtr handle)
       {
           _hwnd = handle;
       }
       public IntPtr Handle
       {
           get { return _hwnd; }
       }
       private IntPtr _hwnd;
   }- Hide quoted text -

- Show quoted text -

Nick,

Thank you for your prompt reply

So what is ShowDialog(IWin32Window) used for? According to
documentation it's to allow a modal dialog to be created on another
window.

Tom
 
N

Nicholas Paldino [.NET/C# MVP]

Tom,

Yes, but with a window created on the same UI thread, definitely not
another thread in the same process, and most definitely not another thread
in another process.

It's simply the handle to the window (created in the same UI thread)
which the dialog being shown will be modal to.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Tom,

Basically, what you are doing is wrong. This is not supported in any
way. The only way to get a window to appear as a child in another process
is to make a call into that process and have the process make the call,
not
your process.

There's no way around it, and if your app eventually breaks in release
mode, you won't have a workaround.

You need to find some other way to do this (if it's possible).

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)




I'm creating a Form in my component and setting it's parent to another
application mains window via ShowDialog(IWin32Window). If I set the
process name to say "Notepad" it works fine, and behaves as expected.
If I set the process name to my main application and do not run it
under VS 2005 is also works properly. Only when I'm debugging the
application does it throw the "Cross-thread operation not valid:
Control accessed from a thread other than the thread it was created
on."
I'm creating the showing the dialog from the same thread, so I don't
see why this error is occuring.
Thread uiThread2 = new Thread(UIThreadProc);
uiThread2.IsBackground = false;
uiThread2.Start(mySession);
private void UIThreadProc(Object mySession)
{
CheckAccountInfo oCheckingInfo = new CheckAccountInfo(mySession);
System.Diagnostics.Process[] procs =
System.Diagnostics.Process.GetProcessesByName("SomeApplication");
if (procs.Length != 0)
{
IntPtr hwnd = procs[0].MainWindowHandle;
// This line causes the mentioned exception while
running in the debugger
Result = oCheckingInfo.ShowDialog(new
WindowWrapper(hwnd));
}
}
public class WindowWrapper : System.Windows.Forms.IWin32Window
{
/// <summary>
///
/// </summary>
/// <param name="handle"></param>
public WindowWrapper(IntPtr handle)
{
_hwnd = handle;
}
public IntPtr Handle
{
get { return _hwnd; }
}
private IntPtr _hwnd;
}- Hide quoted text -

- Show quoted text -

Nick,

Thank you for your prompt reply

So what is ShowDialog(IWin32Window) used for? According to
documentation it's to allow a modal dialog to be created on another
window.

Tom
 
T

Tom C

Tom,

    Yes, but with a window created on the same UI thread, definitely not
another thread in the same process, and most definitely not another thread
in another process.

    It's simply the handle to the window (created in the same UI thread)
which the dialog being shown will be modal to.

--
          - Nicholas Paldino [.NET/C# MVP]
          - (e-mail address removed)


Basically, what you are doing is wrong. This is not supported in any
way. The only way to get a window to appear as a child in another process
is to make a call into that process and have the process make the call,
not
your process.
There's no way around it, and if your app eventually breaks in release
mode, you won't have a workaround.
You need to find some other way to do this (if it's possible).
news:200f8f4e-1fd7-4fa0-abb5-6faaad4439c2@j20g2000hsi.googlegroups.com...
I'm creating a Form in my component and setting it's parent to another
application mains window via ShowDialog(IWin32Window). If I set the
process name to say "Notepad" it works fine, and behaves as expected.
If I set the process name to my main application and do not run it
under VS 2005 is also works properly. Only when I'm debugging the
application does it throw the "Cross-thread operation not valid:
Control accessed from a thread other than the thread it was created
on."
I'm creating the showing the dialog from the same thread, so I don't
see why this error is occuring.
Thread uiThread2 = new Thread(UIThreadProc);
uiThread2.IsBackground = false;
uiThread2.Start(mySession);
private void UIThreadProc(Object mySession)
{
CheckAccountInfo oCheckingInfo = new CheckAccountInfo(mySession);
System.Diagnostics.Process[] procs =
System.Diagnostics.Process.GetProcessesByName("SomeApplication");
if (procs.Length != 0)
{
IntPtr hwnd = procs[0].MainWindowHandle;
// This line causes the mentioned exception while
running in the debugger
Result = oCheckingInfo.ShowDialog(new
WindowWrapper(hwnd));
}
}
public class WindowWrapper : System.Windows.Forms.IWin32Window
{
/// <summary>
///
/// </summary>
/// <param name="handle"></param>
public WindowWrapper(IntPtr handle)
{
_hwnd = handle;
}
public IntPtr Handle
{
get { return _hwnd; }
}
private IntPtr _hwnd;
}- Hide quoted text -
- Show quoted text -

Nick,

Thank you for your prompt reply

So what is ShowDialog(IWin32Window) used for? According to
documentation it's to allow a modal dialog to be created on another
window.

Tom- Hide quoted text -

- Show quoted text -

Nick,

The application that loads my Assembly (via a COM interface) I have no
control over it's not modifiable. My intent was to load my form and
assign it to the main UI of the calling application with Modal
behavior. So my control and the calling application are in the same
process space, I'm just not sure about the UI thread.

Tom
 
N

Nicholas Paldino [.NET/C# MVP]

Tom,

Well, if you are being called from within the same process, then that's
a good thing, but it appears that whatever is calling you clearly doesn't
expect you to interact with the UI if you have to go about this way to
display something to the user (and especially since it is calling you on a
non UI thread).

So the question is, why are you trying to show a UI element when you are
not supposed to? Is there any way that you can pass data back to the caller
to convey your message?


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Tom,

Yes, but with a window created on the same UI thread, definitely not
another thread in the same process, and most definitely not another thread
in another process.

It's simply the handle to the window (created in the same UI thread)
which the dialog being shown will be modal to.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


Basically, what you are doing is wrong. This is not supported in any
way. The only way to get a window to appear as a child in another
process
is to make a call into that process and have the process make the call,
not
your process.
There's no way around it, and if your app eventually breaks in release
mode, you won't have a workaround.
You need to find some other way to do this (if it's possible).
news:200f8f4e-1fd7-4fa0-abb5-6faaad4439c2@j20g2000hsi.googlegroups.com...
I'm creating a Form in my component and setting it's parent to another
application mains window via ShowDialog(IWin32Window). If I set the
process name to say "Notepad" it works fine, and behaves as expected.
If I set the process name to my main application and do not run it
under VS 2005 is also works properly. Only when I'm debugging the
application does it throw the "Cross-thread operation not valid:
Control accessed from a thread other than the thread it was created
on."
I'm creating the showing the dialog from the same thread, so I don't
see why this error is occuring.
Thread uiThread2 = new Thread(UIThreadProc);
uiThread2.IsBackground = false;
uiThread2.Start(mySession);
private void UIThreadProc(Object mySession)
{
CheckAccountInfo oCheckingInfo = new CheckAccountInfo(mySession);
System.Diagnostics.Process[] procs =
System.Diagnostics.Process.GetProcessesByName("SomeApplication");
if (procs.Length != 0)
{
IntPtr hwnd = procs[0].MainWindowHandle;
// This line causes the mentioned exception while
running in the debugger
Result = oCheckingInfo.ShowDialog(new
WindowWrapper(hwnd));
}
}
public class WindowWrapper : System.Windows.Forms.IWin32Window
{
/// <summary>
///
/// </summary>
/// <param name="handle"></param>
public WindowWrapper(IntPtr handle)
{
_hwnd = handle;
}
public IntPtr Handle
{
get { return _hwnd; }
}
private IntPtr _hwnd;
}- Hide quoted text -
- Show quoted text -

Nick,

Thank you for your prompt reply

So what is ShowDialog(IWin32Window) used for? According to
documentation it's to allow a modal dialog to be created on another
window.

Tom- Hide quoted text -

- Show quoted text -

Nick,

The application that loads my Assembly (via a COM interface) I have no
control over it's not modifiable. My intent was to load my form and
assign it to the main UI of the calling application with Modal
behavior. So my control and the calling application are in the same
process space, I'm just not sure about the UI thread.

Tom
 
F

Family Tree Mike

We do similar things to this in creating an extension to a commercial
product. In this, I have not had to try and use the window handle to the
main application. I simply use form.ShowDialog(). Are you sure you need to
assign it to the main UI? When our modal dialog is shown, it behaves as we
expect.
 
T

Tom C

Tom,

    Well, if you are being called from within the same process, then that's
a good thing, but it appears that whatever is calling you clearly doesn't
expect you to interact with the UI if you have to go about this way to
display something to the user (and especially since it is calling you on a
non UI thread).

    So the question is, why are you trying to show a UI element when you are
not supposed to?  Is there any way that you can pass data back to the caller
to convey your message?

--
          - Nicholas Paldino [.NET/C# MVP]
          - (e-mail address removed)


Yes, but with a window created on the same UI thread, definitely not
another thread in the same process, and most definitely not another thread
in another process.
It's simply the handle to the window (created in the same UI thread)
which the dialog being shown will be modal to.
Tom,
Basically, what you are doing is wrong. This is not supported in any
way. The only way to get a window to appear as a child in another
process
is to make a call into that process and have the process make the call,
not
your process.
There's no way around it, and if your app eventually breaks in release
mode, you won't have a workaround.
You need to find some other way to do this (if it's possible).
--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

I'm creating a Form in my component and setting it's parent to another
application mains window via ShowDialog(IWin32Window). If I set the
process name to say "Notepad" it works fine, and behaves as expected..
If I set the process name to my main application and do not run it
under VS 2005 is also works properly. Only when I'm debugging the
application does it throw the "Cross-thread operation not valid:
Control accessed from a thread other than the thread it was created
on."
I'm creating the showing the dialog from the same thread, so I don't
see why this error is occuring.
Thread uiThread2 = new Thread(UIThreadProc);
uiThread2.IsBackground = false;
uiThread2.Start(mySession);
private void UIThreadProc(Object mySession)
{
CheckAccountInfo oCheckingInfo = new CheckAccountInfo(mySession);
System.Diagnostics.Process[] procs =
System.Diagnostics.Process.GetProcessesByName("SomeApplication");
if (procs.Length != 0)
{
IntPtr hwnd = procs[0].MainWindowHandle;
// This line causes the mentioned exception while
running in the debugger
Result = oCheckingInfo.ShowDialog(new
WindowWrapper(hwnd));
}
}
public class WindowWrapper : System.Windows.Forms.IWin32Window
{
/// <summary>
///
/// </summary>
/// <param name="handle"></param>
public WindowWrapper(IntPtr handle)
{
_hwnd = handle;
}
public IntPtr Handle
{
get { return _hwnd; }
}
private IntPtr _hwnd;
}- Hide quoted text -
- Show quoted text -

Thank you for your prompt reply
So what is ShowDialog(IWin32Window) used for? According to
documentation it's to allow a modal dialog to be created on another
window.
Tom- Hide quoted text -
- Show quoted text -

Nick,

The application that loads my Assembly (via a COM interface) I have no
control over it's not modifiable. My intent was to load my form and
assign it to the main UI of the calling application with Modal
behavior. So my control and the calling application are in the same
process space, I'm just not sure about the UI thread.

Tom- Hide quoted text -

- Show quoted text -

Nick,

The calling process is expecting a UI to be presented, that's not the
issue. What sent me down this route was an issue where the data that's
displayed on the main UI is modified by my code, I want the
modifications to reflected in the main ui while my form is displayed
this isn't happening probably because the main UI is processing the
button that launched my code. When my form closes the UI is
immediately updated with my modifications.

So I changed my logic to update the data, spawn a thread, return to
the main UI allowing it to update then my thread present the Form. The
Form must be modal to the main UI, if I simply call ShowDialog() it's
not modal, calling ShowDialog(main UI window handle) produces the
desired results.

Hope this is clear.

Any suggestions?

Tom
 
N

Nicholas Paldino [.NET/C# MVP]

Tom,

Well, you are calling ShowDialog in a thread other than the UI thread,
so that is where the error comes from, and now that you mention it is in the
same process, the answer is rather simple.

You have to marshal the call back to the main thread in order to display
the UI. This is typically done through a call to Invoke, which will send a
windows message to the message pump on the UI thread, along with your
delegate details, and then issue the call on the UI thread.

The thing is, it doesn't seem like you have a Control instance available
to you to make the call on. This is going to make marshaling the call to
the UI that much harder.

There is no way that I can see to take an arbitrary window handle and
then assign it to a Control, which is what you will need to do in order to
get access to an implementation of Invoke that you can call.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Tom,

Well, if you are being called from within the same process, then that's
a good thing, but it appears that whatever is calling you clearly doesn't
expect you to interact with the UI if you have to go about this way to
display something to the user (and especially since it is calling you on a
non UI thread).

So the question is, why are you trying to show a UI element when you are
not supposed to? Is there any way that you can pass data back to the
caller
to convey your message?

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


Yes, but with a window created on the same UI thread, definitely not
another thread in the same process, and most definitely not another
thread
in another process.
It's simply the handle to the window (created in the same UI thread)
which the dialog being shown will be modal to.
Tom,
Basically, what you are doing is wrong. This is not supported in any
way. The only way to get a window to appear as a child in another
process
is to make a call into that process and have the process make the
call,
not
your process.
There's no way around it, and if your app eventually breaks in release
mode, you won't have a workaround.
You need to find some other way to do this (if it's possible).
--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

I'm creating a Form in my component and setting it's parent to
another
application mains window via ShowDialog(IWin32Window). If I set the
process name to say "Notepad" it works fine, and behaves as
expected.
If I set the process name to my main application and do not run it
under VS 2005 is also works properly. Only when I'm debugging the
application does it throw the "Cross-thread operation not valid:
Control accessed from a thread other than the thread it was created
on."
I'm creating the showing the dialog from the same thread, so I don't
see why this error is occuring.
Thread uiThread2 = new Thread(UIThreadProc);
uiThread2.IsBackground = false;
uiThread2.Start(mySession);
private void UIThreadProc(Object mySession)
{
CheckAccountInfo oCheckingInfo = new CheckAccountInfo(mySession);
System.Diagnostics.Process[] procs =
System.Diagnostics.Process.GetProcessesByName("SomeApplication");
if (procs.Length != 0)
{
IntPtr hwnd = procs[0].MainWindowHandle;
// This line causes the mentioned exception while
running in the debugger
Result = oCheckingInfo.ShowDialog(new
WindowWrapper(hwnd));
}
}
public class WindowWrapper : System.Windows.Forms.IWin32Window
{
/// <summary>
///
/// </summary>
/// <param name="handle"></param>
public WindowWrapper(IntPtr handle)
{
_hwnd = handle;
}
public IntPtr Handle
{
get { return _hwnd; }
}
private IntPtr _hwnd;
}- Hide quoted text -
- Show quoted text -

Thank you for your prompt reply
So what is ShowDialog(IWin32Window) used for? According to
documentation it's to allow a modal dialog to be created on another
window.
Tom- Hide quoted text -
- Show quoted text -

Nick,

The application that loads my Assembly (via a COM interface) I have no
control over it's not modifiable. My intent was to load my form and
assign it to the main UI of the calling application with Modal
behavior. So my control and the calling application are in the same
process space, I'm just not sure about the UI thread.

Tom- Hide quoted text -

- Show quoted text -

Nick,

The calling process is expecting a UI to be presented, that's not the
issue. What sent me down this route was an issue where the data that's
displayed on the main UI is modified by my code, I want the
modifications to reflected in the main ui while my form is displayed
this isn't happening probably because the main UI is processing the
button that launched my code. When my form closes the UI is
immediately updated with my modifications.

So I changed my logic to update the data, spawn a thread, return to
the main UI allowing it to update then my thread present the Form. The
Form must be modal to the main UI, if I simply call ShowDialog() it's
not modal, calling ShowDialog(main UI window handle) produces the
desired results.

Hope this is clear.

Any suggestions?

Tom
 
D

David Taylor

I had what I believe to be the same problem today. My application has
various add-ins that extend the functionality, and when an add-in
command executes, it executes on a different thread.

I wanted my add-in to display a modal dialog, and naturally I wanted the
add-in thread to create the form, so that it would have direct access to
controls, without having to use Invoke or Begin Invoke. I supplied the
application main window (IWin32Window) as the owner argument to
ShowDialog.

This failed with a "Cross-thread operation" exception, and looking at
the call stack, it looked like it was trying to stop the message thread
of the owner window (although the exception complained about the dialog
window, not the owner window, which I don't really understand).

Anyway, our add-ins are written to use .NET Remoting, so I also have the
option of running the add-in in a separate app domain in the same
process, or in a separate process. I tried both of these, and in both
cases, ShowDialog worked fine, and I got the correct modal dialog
behavior.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top