| File: Remote\RemoteServiceCallbackDispatcher.cs | Web Access |
| Project: src\roslyn\src\Workspaces\Core\Portable\Microsoft.CodeAnalysis.Workspaces.csproj (Microsoft.CodeAnalysis.Workspaces) |
// 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.Collections.Concurrent; using System.Threading; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.Remote; internal interface IRemoteServiceCallbackDispatcher { RemoteServiceCallbackDispatcher.Handle CreateHandle(object? instance); } internal class RemoteServiceCallbackDispatcher : IRemoteServiceCallbackDispatcher { internal readonly struct Handle(ConcurrentDictionary<RemoteServiceCallbackId, object> callbackInstances, RemoteServiceCallbackId callbackId) : IDisposable { public readonly RemoteServiceCallbackId Id = callbackId; public void Dispose() { Contract.ThrowIfTrue(callbackInstances?.TryRemove(Id, out _) == false); } } private int _callbackId = 1; private readonly ConcurrentDictionary<RemoteServiceCallbackId, object> _callbackInstances = new(concurrencyLevel: 2, capacity: 10); public Handle CreateHandle(object? instance) { if (instance is null) { return default; } var callbackId = new RemoteServiceCallbackId(Interlocked.Increment(ref _callbackId)); var handle = new Handle(_callbackInstances, callbackId); _callbackInstances.Add(callbackId, instance); return handle; } public object GetCallback(RemoteServiceCallbackId callbackId) { Contract.ThrowIfFalse(_callbackInstances.TryGetValue(callbackId, out var instance)); return instance; } }