Creating multi-thread UI has a low probability to crash
- Dominant language
- C#
- Stars
- 7.7k
- Forks
- 1.3k
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 61
Description
* .NET Core Version: 3.0.100-preview-009812
* Windows version: Windows 10.0.18323 19H1
* Does the bug reproduce also in WPF for .NET Framework 4.8?: Yes
**Problem description:**
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.8.
phenomenon:
- An exception is thrown and the application crashes
**Actual behavior:**
```
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.b__0() in C:\Users\lvyi\Desktop\Walterlv.Bugs.MultiThreadedUI\Walterlv.Bugs.MultiThreadedUI\Program.cs:line 33
```

**Expected behavior:**
Don't crash.
**Minimal repro:**
1. Create a new WPF project (either .NET Core 3 or .NET Framework 4.8)
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.

All other files remain the same as the default code generated by Visual Studio, and the code of Program.cs is as follows:
```csharp
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.
```csharp
SynchronizationContext.SetSynchronizationContext(
new DispatcherSynchronizationContext(
Dispatcher.CurrentDispatcher));
```
Contributor guide
Assessment
This issue has not been assessed yet.