多线程无法访问this.close()

时间:2014-07-17 20:17:41

标签: c# wpf multithreading splash-screen opentk

所以我理解你只能从它创建的线程访问UI控件,但是我收到一个错误抱怨'this.Close()'这一行。我要做的是启动一个打开带有OpenTK动画的闪屏的线程。

错误:“调用线程无法访问此对象,因为另一个线程拥有它。”

以下是代码:

  public MainWindow()
    {

        InitializeComponent();

          closeSplashBool = false;              

          Thread t = new Thread(() =>
              {
                  openSplash = new SplashScreen();
                  openSplash.Show();

              }
                  );
          t.SetApartmentState(ApartmentState.STA);
          t.Start(); 

    ///
    /// Long running task
    ///

    closeSplashBool = true;
    }

SplashScreen构造函数中唯一的代码行是InitializeComponents()。这是我的SplashScreen类的动画功能(控制何时关闭启动画面):

        private void splashControl_Paint(object sender, PaintEventArgs e)
    {
        //make sure our GL control has loaded
        if (!loaded)
            return;



        if (animCount <= 0 )
        {
            Thread.Sleep(200);
            if (MainWindow.closeSplash)
                this.Close();  //program crashes on this line
        }
        else if (animCount < 3.75 && animCount >=2.75)
        {
            animCount -= .2f;
            System.Threading.Thread.Sleep(1);
        }
        else if (animCount < 2.75)
        {
            animCount -= .07f;
            System.Threading.Thread.Sleep(5);
        }
        else 
        {
            animCount -= .7f;
            System.Threading.Thread.Sleep(1);
            if (animCount < 0)
                animCount = 0;
        }
        Render();
    }

我在Thread't'中创建了一个'新'的Splash Screen,所以我认为调用'this.Close()'不会有任何访问冲突。我的问题是为什么我会遇到此访问冲突?我尝试用'Dispatcher.InvokeShutdown'替换'this.close'取代其他人的建议,但随后Splash Screen永远不会消失。

1 个答案:

答案 0 :(得分:-1)

请参阅MSDN MethodInvoker Delegate (System.Windows.Forms)

    private void splashControl_Paint(object sender, PaintEventArgs e)
    {
        // see the http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=EN-US&k=k%28SYSTEM.WINDOWS.FORMS.METHODINVOKER%29;k%28TargetFrameworkMoniker-%22.NETFRAMEWORK%2cVERSION%3dV4.0%22%29;k%28DevLang-CSHARP%29&rd=true
        if (!this.IsHandleCreated && !this.IsDisposed) return;

        if (this.InvokeRequired)
        {
            this.Invoke(new MethodInvoker(() => { splashControl_Paint(sender, e); }));
        }
        else
        {
            // place splashControl_Paint CODE HERE
        }
    }