/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/VisualStudio/Core/Def/Utilities/ThreadSafeMenuCommandService.cs
60 строк
2 KB
Jason Malinowski
Avoid switching to the UI thread every time we are subscribing menus
12 мар 2026, 21:06
12 мар 2026, 21:06
64b0b7c
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.ComponentModel.Design; using Microsoft.VisualStudio.Shell; namespace Microsoft.VisualStudio.LanguageServices.Implementation.Utilities; /// <summary> /// Thread-safe wrapper around <see cref="IMenuCommandService"/> that serializes /// all command registrations through a lock so the underlying service's lack of thread /// safety isn't a problem. It can still be used on any thread then, as long as nobody else /// is using it directly. /// </summary> internal sealed class ThreadSafeMenuCommandService { private readonly IMenuCommandService _menuCommandService; private readonly object _gate = new(); public ThreadSafeMenuCommandService(IMenuCommandService menuCommandService) { _menuCommandService = menuCommandService; } /// <summary> /// Adds an <see cref="OleMenuCommand"/> with both an invoke and a before-query-status handler. /// </summary> public OleMenuCommand AddCommand( Guid commandGroup, int commandId, EventHandler invokeHandler, EventHandler beforeQueryStatus) { var commandIdWithGroupId = new CommandID(commandGroup, commandId); var command = new OleMenuCommand(invokeHandler, delegate { }, beforeQueryStatus, commandIdWithGroupId); lock (_gate) { _menuCommandService.AddCommand(command); } return command; } /// <summary> /// Adds a simple <see cref="MenuCommand"/> with only an invoke handler. /// </summary> public MenuCommand AddCommand(Guid commandGroup, int commandId, EventHandler invokeHandler) { var commandIdWithGroupId = new CommandID(commandGroup, commandId); var command = new MenuCommand(invokeHandler, commandIdWithGroupId); lock (_gate) { _menuCommandService.AddCommand(command); } return command; } }