0

Here I have a block of code that executes:

    public override void Execute(XObjectList itemList, ProcessInfo processInfo) {
        ManualResetEvent syncEvent = new ManualResetEvent(false);
        execute(itemList, processInfo);
        //openScreen();
        Thread STAThread = new Thread(() => {
            var window = new Window();
            window.Content = new MailViewerView();
            window.Show();
            syncEvent.Set();
        });
        STAThread.SetApartmentState(ApartmentState.STA);
        STAThread.Start();
        syncEvent.WaitOne();
    }

I expect to after the last line, the window to open and the process itself to stop, but the thread that calls the execute just iterates again and again. Any pointers as to what I am doing wrong?

**UPDATE If I set a time in the syncEvent.WaitOne(), the debug screen of the background process as well as the UI displays, except the UI is not accessible. Any help with this?

**Additional Info I want to do this as the thread that calls the execute method itself is something that I can't access, I want to stop that thread and display the UI for one iteration of it. So it may seem like bad coding, but it is the only way I can think of to get around it.

**UPDATE When doing the following:

        public override void Execute(XObjectList itemList, ProcessInfo processInfo) {
        ManualResetEvent syncEvent = new ManualResetEvent(false);
        execute(itemList, processInfo);

        //openScreen();
        Thread STAThread = new Thread(() => {
            var window = new Window();
            window.Content = new MailViewerView();
            window.Show();
            syncEvent.WaitOne();
            syncEvent.Set();
        });
        STAThread.SetApartmentState(ApartmentState.STA);
        STAThread.Start();
    }

The screen does show and the execute thread is waiting, but nothing on the screen is accessible. Any ideas as to overcome this part?

svbyogibear
  • 333
  • 1
  • 5
  • 19
  • It is just bad code, that window will never be visible. You must run a dispatcher loop, Application.Run() is required. If this code "iterates again and again" then you are going to have a *lot* of windows, best to think a bit about what you really want to accomplish. – Hans Passant Jun 02 '15 at 14:20
  • The code should run over and over again (it is on a scheduler), I just want to hack the native behaviour and display the UI after one iteration. – svbyogibear Jun 02 '15 at 14:22
  • You really cannot create a Window on another thread. It *must* be created and owned by the main thread in order for the message pump to work correctly. This is why your window is not processing any events, you've stalled the message pump. – vcsjones Jun 02 '15 at 14:25
  • The main thread is not an STA thread, and there's no way I can change that as it is a part of a DLL to which I don't have access. That is why I am attempting this hack in the first place. – svbyogibear Jun 02 '15 at 14:40
  • A WPF app can run a window in a background thread fine, if it's set up properly. I'm not clear on exactly what the desired behaviour is - but my guess is that you want to use `window.ShowDialog()` instead of `window.Show()` so that the code waits for your window to be closed before continuing? (Otherwise, I don't see why you're using the `ManualResetEvent` at all...) – Dan Puzey Jun 02 '15 at 14:46
  • I can't believe it is something so small I overlooked, thank you! – svbyogibear Jun 02 '15 at 14:52

1 Answers1

0

So in the end there was nothing wrong with the initial code sample, it would do exactly as intended if I actually called ShowDialog(), as seen here:

        public override void Execute(XObjectList itemList, ProcessInfo processInfo) {
        execute(itemList, processInfo);

        ManualResetEvent syncEvent = new ManualResetEvent(false);
        //openScreen();
        Thread STAThread = new Thread(() => {
            var window = new Window();
            window.Content = new MailViewerView();
            window.ShowDialog();
            syncEvent.Set();
        });
        STAThread.SetApartmentState(ApartmentState.STA);
        STAThread.Start();

        syncEvent.WaitOne();
    }
svbyogibear
  • 333
  • 1
  • 5
  • 19