Esempio n. 1
0
            private Task <StrongBox <ImmutableArray <DiagnosticData> > > DeserializeAsync(DiagnosticDataSerializer serializer, object documentOrProject, object key, string stateKey, CancellationToken cancellationToken)
            {
                // when VS is loading new solution, we will try to find out all diagnostics persisted from previous VS session.
                // in that situation, it is possible that we have a lot of deserialization returning empty result. previously we used to
                // return default(ImmutableArray) for such case, but it turns out async/await framework has allocation issues with returning
                // default(value type), so we are using StrongBox to return no data as null. async/await has optimization where it will return
                // cached empty task if given value is null for reference type. (see AsyncMethodBuilder.GetTaskForResult)
                //
                // right now, we can't use Nullable either, since it is not one of value type the async/await will reuse cached task. in future,
                // if they do, we can change it to return Nullable<ImmutableArray>
                //
                // after initial deserialization, we track actual document/project that actually have diagnostics so no data won't be a common
                // case.
                // check cache first
                if (InMemoryStorage.TryGetValue(_owner.Analyzer, (key, stateKey), out var entry) && serializer.Version == entry.Version)
                {
                    if (entry.Diagnostics.Length == 0)
                    {
                        // if there is no result, use cached task
                        return(s_emptyResultTaskCache);
                    }

                    return(Task.FromResult(new StrongBox <ImmutableArray <DiagnosticData> >(entry.Diagnostics)));
                }

                // try to deserialize it
                return(serializer.DeserializeAsync(documentOrProject, stateKey, cancellationToken));
            }
            private ValueTask <ImmutableArray <DiagnosticData> > DeserializeDiagnosticsAsync(
                IPersistentStorageService persistentService,
                DiagnosticDataSerializer serializer,
                Project project,
                TextDocument?document,
                object key,
                string stateKey,
                CancellationToken cancellationToken
                )
            {
                Contract.ThrowIfFalse(document == null || document.Project == project);

                if (
                    InMemoryStorage.TryGetValue(_owner.Analyzer, (key, stateKey), out var entry) &&
                    serializer.Version == entry.Version
                    )
                {
                    return(ValueTaskFactory.FromResult(entry.Diagnostics));
                }

                return(serializer.DeserializeAsync(
                           persistentService,
                           project,
                           document,
                           stateKey,
                           cancellationToken
                           ));
            }
            private async Task <ImmutableArray <DiagnosticData> > DeserializeAsync(DiagnosticDataSerializer serializer, object documentOrProject, object key, string stateKey, CancellationToken cancellationToken)
            {
                // check cache first
                CacheEntry entry;

                if (InMemoryStorage.TryGetValue(_owner.Analyzer, ValueTuple.Create(key, stateKey), out entry) && serializer.Version == entry.Version)
                {
                    return(entry.Diagnostics);
                }

                // try to deserialize it
                return(await serializer.DeserializeAsync(documentOrProject, stateKey, cancellationToken).ConfigureAwait(false));
            }