C# 多线程无法访问此。关闭()
因此,我知道您只能从创建UI控件的线程访问它,但我收到一个错误,抱怨行“this.Close”。我试图做的是启动一个线程,用OpenTK动画打开一个启动屏幕 错误:调用线程无法访问此对象,因为其他线程拥有它 代码如下:C# 多线程无法访问此。关闭(),c#,wpf,multithreading,splash-screen,opentk,C#,Wpf,Multithreading,Splash Screen,Opentk,因此,我知道您只能从创建UI控件的线程访问它,但我收到一个错误,抱怨行“this.Close”。我试图做的是启动一个线程,用OpenTK动画打开一个启动屏幕 错误:调用线程无法访问此对象,因为其他线程拥有它 代码如下: public MainWindow() { InitializeComponent(); closeSplashBool = false; Thread t = new Thre
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类的动画函数,用于控制何时关闭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();
}
我在线程“t”中创建了一个“新”启动屏幕,因此我认为调用“this.Close”不会有任何访问冲突。我的问题是为什么我会受到这种访问违规?我曾尝试根据其他人的建议将“this.close”替换为“Dispatcher.InvokeShutdown”,但随后闪屏从未消失 参见MSDN
有没有理由不使用内置WPF框架来显示初始屏幕,只需向VS项目添加一个“新项目”->“初始屏幕WPF”?不要创建多个UI线程。你只是自找麻烦。在第一个UI线程中执行非UI工作时,不要创建第二个UI线程来显示UI,只需在一个且唯一的UI线程中显示表单,并在非UI线程中执行非UI工作即可。@AwkwardCoder我从未使用或听说过“New Item”->“SplashScreen WPF”。这与制作新窗口有什么不同?Servy这是我在这一点上的最后手段,但我已经想到了这一点,你是对的,应该可以工作。这是启动屏幕的最简单的解决方案,所以为什么不使用它呢?你可以在UI线程上创建启动屏幕,并创建一个计时器,在你想要的延迟后触发。计时器的事件处理程序将在启动屏幕上调用Close方法。您是说这将消除访问错误?应该是这样的,您测试过了吗?错误:调用线程无法访问此对象,因为其他线程拥有它。表示需要调用。不幸的是,我没有使用WinForms。我正在使用WPF并在WinForms主机控件中托管OpenTK控件。
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
}
}