RecoverableTextAndVersion.cs 2.7 KB
Newer Older
1
// Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
P
Pilchie 已提交
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.Internal.Log;
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis
{
    /// <summary>
    /// A text retainer that will save text to temporary storage when it is evicted from the
    /// text cache and reload from that storage if and when it is needed again.
    /// </summary>
    internal class RecoverableTextAndVersion : RecoverableCachedObjectSource<TextAndVersion>
    {
        private readonly ITemporaryStorageService storageService;

        // these fields are assigned once during call to SaveAsync
20
        private ITemporaryTextStorage storage;
P
Pilchie 已提交
21 22 23 24 25
        private VersionStamp storedVersion;
        private string storedFilePath;

        public RecoverableTextAndVersion(
            ValueSource<TextAndVersion> initialTextAndVersion,
26 27
            ITemporaryStorageService storageService)
            : base(initialTextAndVersion)
P
Pilchie 已提交
28 29 30 31 32 33 34 35 36 37 38 39 40 41
        {
            this.storageService = storageService;
        }

        public bool TryGetTextVersion(out VersionStamp version)
        {
            version = this.storedVersion;
            return version != default(VersionStamp);
        }

        protected override async Task<TextAndVersion> RecoverAsync(CancellationToken cancellationToken)
        {
            Contract.ThrowIfNull(this.storage);

42
            using (Logger.LogBlock(FunctionId.Workspace_Recoverable_RecoverTextAsync, this.storedFilePath, cancellationToken))
P
Pilchie 已提交
43 44 45 46 47 48 49 50
            {
                var text = await this.storage.ReadTextAsync(cancellationToken).ConfigureAwait(false);
                return TextAndVersion.Create(text, this.storedVersion, this.storedFilePath);
            }
        }

        protected override TextAndVersion Recover(CancellationToken cancellationToken)
        {
51
            using (Logger.LogBlock(FunctionId.Workspace_Recoverable_RecoverText, this.storedFilePath, cancellationToken))
P
Pilchie 已提交
52 53 54 55 56 57
            {
                var text = this.storage.ReadText(cancellationToken);
                return TextAndVersion.Create(text, this.storedVersion, this.storedFilePath);
            }
        }

58
        protected override Task SaveAsync(TextAndVersion textAndVersion, CancellationToken cancellationToken)
P
Pilchie 已提交
59
        {
60
            this.storage = this.storageService.CreateTemporaryTextStorage(CancellationToken.None);
P
Pilchie 已提交
61 62
            this.storedVersion = textAndVersion.Version;
            this.storedFilePath = textAndVersion.FilePath;
63
            return storage.WriteTextAsync(textAndVersion.Text);
P
Pilchie 已提交
64 65
        }
    }
66
}