内容简介: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:
- 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
- These UI threads all display WPF windows
- 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:
How to Reproduce
- Create a new WPF project (either .NET Core 3 or .NET Framework 4.7.2)
- Keep the automatically generated
App
andMainWindow
unchanged, we create a new windowSplashWindow
. - Create a new
Program
class containing the Main function and setProgram
as the startup object (instead ofApp
) in the project properties.
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 ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 吕毅 (包含链接:https://walterlv.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 (walter.lv@qq.com) 。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。