Пример #1
0
        /// <summary>
        ///     Opens a new window on it's own thread and shows it.
        /// </summary>
        /// <remarks>
        ///     Make sure to access this window using Window.Dispatcher.BeginInvoke.
        /// </remarks>
        /// <param name="path">Optional photo to open in new window.</param>
        /// <returns>The new Window.</returns>
        private void OpenPhotoWindowOnNewThread(PhotoWindowData?data = null)
        {
            Thread thread = new Thread(() => {
                PhotoWindow window = (data != null) ?
                                     new PhotoWindow(new PhotoWindowViewModel(data)) :
                                     new PhotoWindow();
                window.Closed += (s, e) =>
                                 window.Dispatcher.InvokeShutdown();
                photoWindows.Add(window);
                window.Show();
                Dispatcher.Run();
            });

            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
        }
        public void Add(PhotoWindow window)
        {
            /*
             * Dispatching to window thread so that it will be in the correct thread-local collection,
             * also this makes the combination of adding the window and hooking up the closed event
             * effectively atomic since close and the closed event are only called on the ui thread.
             */
            window.Dispatcher.BeginInvoke(() => {
                LinkedList <PhotoWindow> windowsForThisThread = threadLocalWindows.Value !;

                int cachedCloseState;
                lock (windowsForThisThread) {
                    cachedCloseState = closeAllForever;

                    /*
                     * Need to check closeAllForever inside lock because we don't want
                     * a thread setting it and closing our thread local windows
                     * between this check and this add, otherwise the window will be
                     * added too late and not closed.
                     */
                    if (cachedCloseState == CLOSE_FOREVER_OFF)
                    {
                        windowsForThisThread.AddLast(window);
                    }
                }

                switch (cachedCloseState)
                {
                case CLOSE_FOREVER_OFF:
                    window.Closed += WindowClosed;
                    break;

                case CLOSE_FOREVER_ON_PERSIST:
                    window.Close(true);
                    break;

                case CLOSE_FOREVER_ON_DONT_PERSIST:
                    window.Close(false);
                    break;
                }
            });
        }