我要在Button单击事件中从窗口A打开窗口B,如下所示:
MainWindow mainWin = new MainWindow();
mainWin.Show();
问题在于MainWindow构造函数中有InitializeComponent方法和其他一些方法,它需要几秒钟的时间执行,从而阻塞了UI(我有一个旋转的图标,它不会旋转)。
这是我尝试过的:
await Task.Run(() => mainWin = new MainWindow()); // Exception: thread must be STA :(
和
await Dispatcher.InvokeAsync(new Action(() => mainWin = new MainWindow()));
和
await Dispatcher.BeginInvoke(new Action(async delegate {
mainWin = new MainWindow();
}));
编辑:这是MainWindow构造函数的外观:
public MainWindow()
{
InitializeComponent(); // Takes about 3 seconds...
}
绝不是我是C#或WPF或线程专家,我找到了这些“解决方案”,而我只是尝试了但没有成功。我想知道是否有一种方法可以异步执行InitializeComponent或如何保持动画播放。
我正在使用C#WPF(无MVVM)和.NET Framework 4.6。预先谢谢你。
答案 0 :(得分:-1)
您可以在另一个线程中创建窗口。缺点是必须通过Dispatcher.Invoke / BeginInvoke从主线程访问该窗口的控件。
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.IO;
using System.Threading;
using System.Windows.Threading;
namespace WpfApplication1
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
void ThreadProc()
{
//create second window in background thread
Window window2 = new Window2();
window2.Show();
//start WPF message loop
DispatcherFrame frame = new DispatcherFrame();
Dispatcher.PushFrame(frame);
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
//start background thread
Thread thread2;
thread2 = new Thread(ThreadProc);
thread2.IsBackground = true;
thread2.SetApartmentState(ApartmentState.STA);
thread2.Start();
}
// To access Window2 from MainWindow, do like that:
//window2.Dispatcher.Invoke(() => { window2.Title = "Hello, world"; });
}
}