WPF's multi-threaded UI is not thread safe

栏目: ASP.NET · 发布时间: 5年前

内容简介:WPF supports multiple UI threads in its framework. You can create multiple UI thread windows or create multiple UI threads in a single window. But unfortunately, this is not really thread-safe.There is a very low probability that WPF application will crash

WPF supports multiple UI threads in its framework. You can create multiple UI thread windows or create multiple UI threads in a single window. But unfortunately, this is not really thread-safe.

There is a very low probability that WPF application will crash when you creating a multi-thread UI. In this post, I’ll tell how this happens.

The Issue

Necessary conditions:

  1. Create multiple WPF UI threads
    • In fact, two are enough, one is the main UI thread with the App class we usually write; a background UI thread, for example, to display the UI thread that starts the splash screen.
    • If you use two threads, you need a lot of repetitive trials to reproduce; and by creating more threads you can greatly improve the probability of a single recurrence
  2. These UI threads all display WPF windows
  3. This issue will occur in both WPF on .NET Core 3 and WPF on .NET Framework 4.7.2.

phenomenon:

- An exception is thrown and the application crashes

For example, the following is one of the exceptions:

Exception thrown: 'System.NullReferenceException' in WindowsBase.dll
Object reference not set to an instance of an object.

System.NullReferenceException: Object reference not set to an instance of an object.
   at System.IO.Packaging.PackagePart.CleanUpRequestedStreamsList()
   at System.IO.Packaging.PackagePart.GetStream(FileMode mode, FileAccess access)
   at System.Windows.Application.LoadComponent(Object component, Uri resourceLocator)
   at Walterlv.Bugs.MultiThreadedUI.SplashWindow.InitializeComponent() in C:\Users\lvyi\Desktop\Walterlv.Bugs.MultiThreadedUI\Walterlv.Bugs.MultiThreadedUI\SplashWindow.xaml:line 1
   at Walterlv.Bugs.MultiThreadedUI.SplashWindow..ctor() in C:\Users\lvyi\Desktop\Walterlv.Bugs.MultiThreadedUI\Walterlv.Bugs.MultiThreadedUI\SplashWindow.xaml.cs:line 24
   at Walterlv.Bugs.MultiThreadedUI.Program.<>c__DisplayClass1_0.<RunSplashWindow>b__0() in C:\Users\lvyi\Desktop\Walterlv.Bugs.MultiThreadedUI\Walterlv.Bugs.MultiThreadedUI\Program.cs:line 33

The following image is an exception caught in WPF on .NET Core 3 that is shown in visual studio 2019:

WPF's multi-threaded UI is not thread safe

How to Reproduce

  1. Create a new WPF project (either .NET Core 3 or .NET Framework 4.7.2)
  2. Keep the automatically generated App and MainWindow unchanged, we create a new window SplashWindow .
  3. Create a new Program class containing the Main function and set Program as the startup object (instead of App ) in the project properties.

WPF's multi-threaded UI is not thread safe

All other files remain the same as the default code generated by Visual Studio, and the code of Program.cs is as follows:

using System;
using System.Threading;
using System.Windows.Threading;

namespace Walterlv.Bugs.MultiThreadedUI
{
    public class Program
    {
        [STAThread]
        private static void Main(string[] args)
        {
            for (var i = 0; i < 50; i++)
            {
                RunSplashWindow(i);
            }

            var app = new App();
            app.InitializeComponent();
            app.Run();
        }

        private static void RunSplashWindow(int index)
        {
            var thread = new Thread(() =>
            {
                var window = new SplashWindow
                {
                    Title = $"SplashWindow {index.ToString().PadLeft(2, ' ')}",
                };
                window.Show();
                Dispatcher.Run();
            })
            {
                IsBackground = true,
            };
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
        }
    }
}

Remarks: Even if you add this code just before the Splash Window creating, this exception still occurs.

SynchronizationContext.SetSynchronizationContext(
    new DispatcherSynchronizationContext(
        Dispatcher.CurrentDispatcher));

本文会经常更新,请阅读原文: https://walterlv.com/post/wpf-multi-thread-ui-is-not-thread-safe-en.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

WPF's multi-threaded UI is not thread safe 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 吕毅 (包含链接:https://walterlv.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 (walter.lv@qq.com)


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

网易一千零一夜

网易一千零一夜

网易杭研项目管理部 / 电子工业出版社 / 2016-9-1 / 46

本书是网易杭州研究院项目管理部多年来丰富的项目管理实践总结与干货分享。字字句句凝结了网易项目经理的甘与苦、汗与泪。 全书围绕项目管理体系,从敏捷实践、项目立项、需求管理、沟通管理,到计划进度管理、风险管理,真实反映了网易面向互联网产品项目管理实战经验与心路历程。 不论你是项目管理新手,还是资深项目经理,都可以从本书中获得启发与借鉴。一起来看看 《网易一千零一夜》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试