dotnet / dotnet/wpf

Creating multi-thread UI has a low probability to crash

Open
#297 9 comments 6 reactions 0 assignees View on GitHub
Bug
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
```

![The exception caught in Visual Studio 2019](https://user-images.githubusercontent.com/9959623/51883630-bd685300-23be-11e9-9c71-a0a8d8d929e3.png)

**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.

![The project structure](https://user-images.githubusercontent.com/9959623/51883617-acb7dd00-23be-11e9-970d-d3581d5dab41.png)

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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.