views:

1502

answers:

3

I am using Wndows XP SP3 x86 + VSTS 2008 to write a simple Windows Forms application using C#. There is a button called button1 and here is the event handler for its click event, when executing the if statement, there is Microsoft.VisualStudio.Debugger.Runtime.CrossThreadMessagingException. Does anyone have any good ideas what is wrong?

private void button1_Click(object sender, EventArgs e)
{
    string recording = ConfigurationSettings.AppSettings["recording"];

    // exception thrown when executing the following if statement
    if (recording.Equals("enable", StringComparison.InvariantCultureIgnoreCase))
    {
        CameraEncoder.Stop();
    }
}

Some more code:

static WMEncoder CameraEncoder = new WMEncoder();

EDIT1:

I am confused how to apply Marc's idea of using Invoke in my code. Should I use the following code segment?

CameraEncoder.Invoke((MethodInvoker) delegate
{
        CameraEncoder.Stop();
});
+2  A: 

Normally, the problem when we see this (regularly) is something like a worker thread or a timer updating the UI - but a button click should be raised through the UI thread, so I don't think it is the "usual problem".

So: what is camera? And what is Recording? Neither is explained, and we can't guess without introducing extra variables...

Depending on what they are, maybe this'll work...

camera.Invoke((MethodInvoker) delegate
{
    if (camera.Equals("enable", StringComparison.InvariantCultureIgnoreCase))
    {
        Recording.Stop();
    }        
});

But without knowing what canera is, I'm clutching at straws...

Marc Gravell
Thanks Marc! 1. There is typo and no camera object, only recording object as string. My bad. :-) 2. CameraEncoder is a Windows Media Encoder object which I starts it in Form Load method, but I do not think it is CameraEncoder's issue since when executing if statement (not hit CameraEncoder.Stop yet), there is such exception. Any ideas to analyze further? 3. I find on Windows Vista and Windows Server 2003, my code works fine, only has issues on Windows XP.
George2
What is "MethodInvoker"? I did not find a keyword or function named "MethodInvoker" in C#?
George2
MethodInvoker is a delegate type in System.Windows.Forms - that simply returns void and accepts no parameters.
Marc Gravell
Re the update: I strongly suspect that the exception is actionally on the Stop(); line... a string equality test doesn't trigger thread affinity. Do you have any event handlers on events from the CameraEncoder? I wonder if that is the real issue...
Marc Gravell
A further question, 1. can we create WMEncoder object from main GUI thread? 2. "I strongly suspect that the exception is actionally on the Stop(); line" -- but exception thrown before we reach Stop line in VSTS, why you think exception will be caused by some line of code which is not executed yet? :-) 3. I only call Start/Stop method of WMEncoder, no event on the instance of this type. Any further ideas?
George2
4. You use camera.Invoke to fix issue that you think in UI thread (callback of button click event handler), we should not call method of other class?
George2
1: I would assume that you should *only* create it there; 2: debuggers are often off by a line or so, and strings don't have thread-affinity
Marc Gravell
4: "we should not call method of other class?" - sorry, I don't understand the question
Marc Gravell
Thanks Marc, 1. so you suggest to create WMEncoder object in the main UI thread? I have this confusion because clemahieu mentioned below that seems we should not create WMEncoder object in the main UI thread. Appreciate if you could clarify. :-) 2. How do you prove it is the Stop method issue? 3. Sorry for my bad English, my question is, why you think using Invoke will solve my issue -- because Invoke will execute the instructions in another thread other than the main UI thread?
George2
4. Another confusion is how to use your Invoke method in my code since there are some typo in my original code. I have posted my new code in my original reply EDIT1 section, please have a review whether my code is correct? Invoke and MethodInvoker is new to me. :-)
George2
1: I can see clemahieu saying **do** create it on the UI thread... how are you currently creating it? 2: perhaps add some trace info "about to do this", "did this", etc. Re the "why" - Control.Invoke pushes work onto the thread that owns a component, which (for controls) should be the UI thread. It sounds very much like you are creating this control on a non-UI thread...
Marc Gravell
Re 4: does it work? If so use it, if not don't.
Marc Gravell
1. Marc, sorry for my bad English, let me final confirm, you mean we can create WMEncoder object inside UI thread correct? 2. I think your solution of using Invoke is on the basis that you think we should access Stop method of WMEncoder from the main UI thread, correct? But WMEncoder is not a Windows Forms control, it is from Windows Media Encoder 9 SDK, so it does not have the inherited Invoke method. I am confused how to apply your solution. Appreciate if you could clarify. :-)
George2
3. "It sounds very much like you are creating this control on a non-UI thread" -- I declare a static object of WMEncoer named CameraEncoder as a static member of the Forms class (the form class composites button control), in this case does the CameraEncoder created by main UI thread or not?
George2
OK, I don't have the WM SDK, so I can't try it; if there is no Invoke then.... hmmm... don't know. Have you *tried* keeping the encoder local to the form and creating it on the UI thread?
Marc Gravell
+1  A: 

Maybe the camera object is created and managed by another thread.. Could you expose more code regarding the camera object?

AlexDrenea
Sorry my typo, there is no camera object, just recordering object as string, any ideas what is wrong?
George2
+1  A: 

I know WMEncoder is a COM object. You might try creating CameraEncoder in the GUI thread instead of a different thread.

I declare it as static object, so which thread creates the static object, main GUI thread? How to prove it?
George2
I declare it as static object -- I mean I declare it as static object in the forms class.
George2
"You might try creating CameraEncoder in the GUI thread instead of a different thread." -- yes, but what is wrong?
George2
I haven't done COM in a long time but there is the concept of Single Threaded Apartment and Multi Threaded Apartment. In STA a COM object receives function calls through a background window message queue. This is the same type of message queue that GUI elements use; you get a similar exception with cross-thread GUI calls.
"you get a similar exception with cross-thread GUI calls" -- I agree. But I am creating a WMEncoder object in the main UI thread, not making cross-thread GUI calls. Are they the same thing as you mentioned?
George2