public override async Task<TextAndVersion> LoadTextAndVersionAsync(Workspace workspace, DocumentId documentId, CancellationToken cancellationToken) { DateTime prevLastWriteTime = File.GetLastWriteTimeUtc(this.path); // Open file for reading with FileShare mode read/write/delete so that we do not lock this file. // Allowing other theads/processes to write or delete the file is essential for scenarios such as // Rename refactoring where File.Replace API is invoked for updating the modified file. TextAndVersion textAndVersion; using (var stream = File.Open(this.path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete)) { var version = VersionStamp.Create(prevLastWriteTime); var memoryStream = await this.ReadStreamAsync(stream, cancellationToken: cancellationToken).ConfigureAwait(false); var text = CreateText(memoryStream, workspace); textAndVersion = TextAndVersion.Create(text, version, path); } // this has a potential to return corrupted state text if someone changed text in the middle of us reading it. // previously, we attempted to detect such case and return empty string with workspace failed event. // but that is nothing better or even worse than returning what we have read so far. // // I am letting it to return what we have read so far. and hopefully, file change event let us re-read this file. // (* but again, there is still a chance where file change event happens even before writing has finished which ends up // let us stay in corrupted state) DateTime newLastWriteTime = File.GetLastWriteTimeUtc(this.path); if (!newLastWriteTime.Equals(prevLastWriteTime)) { // TODO: remove this once we know how often this can happen. // I am leaving this here for now for diagnostic purpose. var message = string.Format(WorkspacesResources.FileWasExternallyModified, this.path); workspace.OnWorkspaceFailed(new DocumentDiagnostic(WorkspaceDiagnosticKind.FileAccessFailure, message, documentId)); } return textAndVersion; }
/// <exception cref="IOException"></exception> public override async Task <TextAndVersion> LoadTextAndVersionAsync(Workspace workspace, DocumentId documentId, CancellationToken cancellationToken) { DateTime prevLastWriteTime = FileUtilities.GetFileTimeStamp(this.path); TextAndVersion textAndVersion; using (var stream = FileUtilities.OpenAsyncRead(this.path)) { System.Diagnostics.Debug.Assert(stream.IsAsync); var version = VersionStamp.Create(prevLastWriteTime); var memoryStream = await this.ReadStreamAsync(stream, cancellationToken : cancellationToken).ConfigureAwait(false); var text = CreateText(memoryStream, workspace); textAndVersion = TextAndVersion.Create(text, version, path); } // this has a potential to return corrupted state text if someone changed text in the middle of us reading it. // previously, we attempted to detect such case and return empty string with workspace failed event. // but that is nothing better or even worse than returning what we have read so far. // // I am letting it to return what we have read so far. and hopefully, file change event let us re-read this file. // (* but again, there is still a chance where file change event happens even before writing has finished which ends up // let us stay in corrupted state) DateTime newLastWriteTime = FileUtilities.GetFileTimeStamp(this.path); if (!newLastWriteTime.Equals(prevLastWriteTime)) { // TODO: remove this once we know how often this can happen. // I am leaving this here for now for diagnostic purpose. var message = string.Format(WorkspacesResources.FileWasExternallyModified, this.path); workspace.OnWorkspaceFailed(new DocumentDiagnostic(WorkspaceDiagnosticKind.Failure, message, documentId)); } return(textAndVersion); }
private TextAndVersion CreateFailedText(Workspace workspace, DocumentId documentId, string message) { // Notify workspace for backwards compatibility. workspace.OnWorkspaceFailed(new DocumentDiagnostic(WorkspaceDiagnosticKind.Failure, message, documentId)); Location location; string display; var filePath = FilePath; if (filePath == null) { location = Location.None; display = documentId.ToString(); } else { location = Location.Create(filePath, textSpan: default, lineSpan: default);
/// <summary> /// Load a text and a version of the document in the workspace. /// </summary> /// <exception cref="IOException"></exception> public override async Task <TextAndVersion> LoadTextAndVersionAsync(Workspace workspace, DocumentId documentId, CancellationToken cancellationToken) { DateTime prevLastWriteTime = FileUtilities.GetFileTimeStamp(_path); TextAndVersion textAndVersion; using (var stream = FileUtilities.OpenAsyncRead(_path)) { var version = VersionStamp.Create(prevLastWriteTime); Contract.Requires(stream.Position == 0); // we do this so that we asynchronously read from file. and this should allocate less for IDE case. // but probably not for command line case where it doesn't use more sophisticated services. using (var readStream = await SerializableBytes.CreateReadableStreamAsync(stream, cancellationToken: cancellationToken).ConfigureAwait(false)) { var text = CreateText(readStream, workspace); textAndVersion = TextAndVersion.Create(text, version, _path); } } // this has a potential to return corrupted state text if someone changed text in the middle of us reading it. // previously, we attempted to detect such case and return empty string with workspace failed event. // but that is nothing better or even worse than returning what we have read so far. // // I am letting it to return what we have read so far. and hopefully, file change event let us re-read this file. // (* but again, there is still a chance where file change event happens even before writing has finished which ends up // let us stay in corrupted state) DateTime newLastWriteTime = FileUtilities.GetFileTimeStamp(_path); if (!newLastWriteTime.Equals(prevLastWriteTime)) { // TODO: remove this once we know how often this can happen. // I am leaving this here for now for diagnostic purpose. var message = string.Format(WorkspacesResources.FileWasExternallyModified, _path); workspace.OnWorkspaceFailed(new DocumentDiagnostic(WorkspaceDiagnosticKind.Failure, message, documentId)); } return(textAndVersion); }
public override async Task <TextAndVersion> LoadTextAndVersionAsync(Workspace workspace, DocumentId documentId, CancellationToken cancellationToken) { DateTime prevLastWriteTime = File.GetLastWriteTimeUtc(this.path); // Open file for reading with FileShare mode read/write/delete so that we do not lock this file. // Allowing other theads/processes to write or delete the file is essential for scenarios such as // Rename refactoring where File.Replace API is invoked for updating the modified file. TextAndVersion textAndVersion; using (var stream = File.Open(this.path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete)) { var version = VersionStamp.Create(prevLastWriteTime); var memoryStream = await this.ReadStreamAsync(stream, cancellationToken : cancellationToken).ConfigureAwait(false); var text = CreateText(memoryStream, workspace); textAndVersion = TextAndVersion.Create(text, version, path); } // this has a potential to return corrupted state text if someone changed text in the middle of us reading it. // previously, we attempted to detect such case and return empty string with workspace failed event. // but that is nothing better or even worse than returning what we have read so far. // // I am letting it to return what we have read so far. and hopefully, file change event let us re-read this file. // (* but again, there is still a chance where file change event happens even before writing has finished which ends up // let us stay in corrupted state) DateTime newLastWriteTime = File.GetLastWriteTimeUtc(this.path); if (!newLastWriteTime.Equals(prevLastWriteTime)) { // TODO: remove this once we know how often this can happen. // I am leaving this here for now for diagnostic purpose. var message = string.Format(WorkspacesResources.FileWasExternallyModified, this.path); workspace.OnWorkspaceFailed(new DocumentDiagnostic(WorkspaceDiagnosticKind.FileAccessFailure, message, documentId)); } return(textAndVersion); }
/// <summary> /// Load a text and a version of the document in the workspace. /// </summary> /// <exception cref="IOException"></exception> public override async Task<TextAndVersion> LoadTextAndVersionAsync(Workspace workspace, DocumentId documentId, CancellationToken cancellationToken) { DateTime prevLastWriteTime = FileUtilities.GetFileTimeStamp(_path); TextAndVersion textAndVersion; using (var stream = FileUtilities.OpenAsyncRead(_path)) { var version = VersionStamp.Create(prevLastWriteTime); Contract.Requires(stream.Position == 0); // we do this so that we asynchronously read from file. and this should allocate less for IDE case. // but probably not for command line case where it doesn't use more sophisticated services. using (var readStream = await SerializableBytes.CreateReadableStreamAsync(stream, cancellationToken: cancellationToken).ConfigureAwait(false)) { var text = CreateText(readStream, workspace); textAndVersion = TextAndVersion.Create(text, version, _path); } } // this has a potential to return corrupted state text if someone changed text in the middle of us reading it. // previously, we attempted to detect such case and return empty string with workspace failed event. // but that is nothing better or even worse than returning what we have read so far. // // I am letting it to return what we have read so far. and hopefully, file change event let us re-read this file. // (* but again, there is still a chance where file change event happens even before writing has finished which ends up // let us stay in corrupted state) DateTime newLastWriteTime = FileUtilities.GetFileTimeStamp(_path); if (!newLastWriteTime.Equals(prevLastWriteTime)) { // TODO: remove this once we know how often this can happen. // I am leaving this here for now for diagnostic purpose. var message = string.Format(WorkspacesResources.FileWasExternallyModified, _path); workspace.OnWorkspaceFailed(new DocumentDiagnostic(WorkspaceDiagnosticKind.Failure, message, documentId)); } return textAndVersion; }