microsoft / microsoft/vs-threading

Dispatcher-based JoinableTaskFactory should post messages more conservatively

Open
#1,272 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
C#
Stars
1k
Forks
160
Avg merge
1d 12h
Merged PRs (30d)
28

Description

In Visual Studio, we have case where 500MB or more in memory is occupied with already-executed SingleExecuteProtector objects in the WPF Dispatcher's queue. To avoid deadlocks in cases of modal dialogs, we always post every request to the UI thread via the JTF as well as a queue backed by Windows or some GUI framework. This provides at least two avenues for every main thread work item to be completed, often leaving the lower-level queue filled with dead work items.

We want to reduce the strain this puts on memory and CPU to hold and eventually process and dump these dead objects.

The proposal is for the JoinableTaskFactory.PostToUnderlyingSynchronizationContext method to enqueue to its own private queue, from which it can trim dead work items opportunistically. It will necessarily also queue a work item to whatever the lower-level queue is as it does today, except that it will take care to only do this if there isn't already such a work item in that queue. When that work item is serviced, that JTF object will process some or all of its private queue. If it yields control while its queue is non-empty, it will post another item to the lower level queue to request more time later.

The most aggravated case is that of the WPF Dispatcher, which is enqueued here:

https://github.com/microsoft/vs-threading/blob/9065e6e4b5593e6ed6e3ff0a9159d4e2765430d6/src/Microsoft.VisualStudio.Threading/DispatcherExtensions.cs#L70

We should consider adding the private queue and management functions to the base class, such that all derived classes can opt into using it easily. The default implementation and this WPF override are likely to both benefit. The derived type in Visual Studio that schedule work to TaskSchedulers may want to participate as well.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with JoinableTaskFactory.PostToUnderlyingSynchronizationContext and the WPF enqueue path in src/Microsoft.VisualStudio.Threading/DispatcherExtensions.cs around line 70. Compare the base implementation with the WPF override and consider how the proposed private queue would be managed. Done means requests avoid redundant lower-level posts while queued work can still be processed and resumed safely.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
backend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.