提交 f364971e 编写于 作者: J Jason Malinowski

Defer reading of the metadata timestamp until later

When we were creating new metadata reference snapshots, we were reading
the timestamp far earlier than needed; all that matters is we actually
read it prior to reading it.

This change is a fairly paranoid change as I try to preserve existing
semantics (and perhaps bugs too). This area is quite sensitive.
上级 e75040ad
......@@ -4,6 +4,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Execution;
using Microsoft.CodeAnalysis.Host;
......@@ -31,7 +32,7 @@ internal partial class VisualStudioMetadataReference
internal sealed class Snapshot : PortableExecutableReference, ISupportTemporaryStorage
{
private readonly VisualStudioMetadataReferenceManager _provider;
private readonly DateTime _timestamp;
private readonly Lazy<DateTime> _timestamp;
private Exception _error;
internal Snapshot(VisualStudioMetadataReferenceManager provider, MetadataReferenceProperties properties, string fullPath)
......@@ -40,20 +41,29 @@ internal Snapshot(VisualStudioMetadataReferenceManager provider, MetadataReferen
Contract.Requires(Properties.Kind == MetadataImageKind.Assembly);
_provider = provider;
try
{
_timestamp = FileUtilities.GetFileTimeStamp(this.FilePath);
}
catch (IOException e)
{
// Reading timestamp of a file might fail.
// Let's remember the failure and report it to the compiler when it asks for metadata.
_error = e;
}
_timestamp = new Lazy<DateTime>(() => {
try
{
return FileUtilities.GetFileTimeStamp(this.FilePath);
}
catch (IOException e)
{
// Reading timestamp of a file might fail.
// Let's remember the failure and report it to the compiler when it asks for metadata.
// We could let the Lazy hold onto this (since it knows how to rethrow exceptions), but
// our support of GetStorages needs to gracefully handle the case where we have no timestamp.
// If Lazy had a "IsValueFaulted" we could be cleaner here.
_error = e;
return DateTime.MinValue;
}
}, LazyThreadSafetyMode.PublicationOnly);
}
protected override Metadata GetMetadataImpl()
{
// Fetch the timestamp first, so as to populate _error if needed
var timestamp = _timestamp.Value;
if (_error != null)
{
throw _error;
......@@ -61,7 +71,7 @@ protected override Metadata GetMetadataImpl()
try
{
return _provider.GetMetadata(this.FilePath, _timestamp);
return _provider.GetMetadata(this.FilePath, timestamp);
}
catch (Exception e) when (SaveMetadataReadingException(e))
{
......@@ -98,7 +108,7 @@ private string GetDebuggerDisplay()
public IEnumerable<ITemporaryStreamStorage> GetStorages()
{
return _provider.GetStorages(this.FilePath, _timestamp);
return _provider.GetStorages(this.FilePath, _timestamp.Value);
}
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册