WPF在新线程上打开窗体

当WPF应用程序运行时,默认会创建一个UI主线程(因为至少需要一个),并在该UI线程上启动消息循环。直到消息循环结束,应用程序就随即退出。那么,问题就来了,能不能创建新线程,然后在新线程上打开一个新窗口实例?这样可以让不同窗口运行在不同的线程上,一定程度上可以相互“独立”。

其实呢,完全的独立运转似乎不太可能,毕竟嘛,线程是抢占 CPU 时间片的,即各个线程间是交替运行的,现在处理器基本是N核的,可以结合并发一起用(在.net 中,使用 Task 可以自动并发)。不管怎么说吧,对UI的响应能力应该能有所改善的。

代码

TaskCompletionSource 类可以从其他来源获得代码执行结果,然后生成一个带Result 的Task实例,有了这个Task实例就可以使用异步等待语法了(await操作符)。由于我们这个地方只是Show一个窗口就完事了,不需要产生执行结果,但是,TaskCompletionSource类有一个泛型参数,用以指定执行结果。

这里咱们可以这样,实例化TaskCompletionSource时设定泛型参数类型为object,然后把代码的执行结果设置为 null。要设置执行结果,请调用 SetResult 方法,要得到生成的Task实例,请访问 Task 属性。

private Task RunNewWindowAsync<TWindow>() where TWindow : System.Windows.Window, new()
{
    TaskCompletionSource<object> tc = new TaskCompletionSource<object>();
    // 新线程
    Thread t = new Thread(() =>
    {
        TWindow win = new TWindow();
        if (win is CusSplashScreen)
            m_cusSplash = win as CusSplashScreen;
        win.Closed += (d, k) =>
        {
            // 当窗口关闭后马上结束消息循环
            System.Windows.Threading.Dispatcher.ExitAllFrames();
        };
        win.Show();
        // Run 方法必须调用,否则窗口一打开就会关闭
        // 因为没有启动消息循环
        System.Windows.Threading.Dispatcher.Run();
        // 这句话是必须的,设置Task的运算结果
        // 但由于此处不需要结果,故用null
        tc.SetResult(null);
    });
    t.SetApartmentState(ApartmentState.STA);
    t.Start();
    // 新线程启动后,将Task实例返回
    // 以便支持 await 操作符
    return tc.Task;
}
调用方法
Button b = e.Source as Button;
b.IsEnabled = false;
await RunNewWindowAsync<SecondWindow>(); //可异步等待
b.IsEnabled = true;

示例代码下载

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值