diff --git a/src/Main/Base/Project/Src/Internal/Templates/Project/CombineDescriptor.cs b/src/Main/Base/Project/Src/Internal/Templates/Project/CombineDescriptor.cs index 770acd97c8..378a7e7300 100644 --- a/src/Main/Base/Project/Src/Internal/Templates/Project/CombineDescriptor.cs +++ b/src/Main/Base/Project/Src/Internal/Templates/Project/CombineDescriptor.cs @@ -26,7 +26,7 @@ namespace ICSharpCode.SharpDevelop.Internal.Templates string name; string startupProject = null; string relativeDirectory = null; - + #region public properties public string StartupProject { get { @@ -77,10 +77,10 @@ namespace ICSharpCode.SharpDevelop.Internal.Templates // Create sub projects foreach (ProjectDescriptor projectDescriptor in projectDescriptors) { IProject newProject = projectDescriptor.CreateProject(projectCreateInformation, defaultLanguage); - if (newProject != null) { - newProject.Location = FileUtility.GetRelativePath(oldCombinePath, newProject.FileName); - newCombine.AddFolder(newProject); - } + if (newProject == null) + return null; + newProject.Location = FileUtility.GetRelativePath(oldCombinePath, newProject.FileName); + newCombine.AddFolder(newProject); projectCreateInformation.CreatedProjects.Add(newProject.FileName); } @@ -92,7 +92,7 @@ namespace ICSharpCode.SharpDevelop.Internal.Templates projectCreateInformation.CombinePath = oldCombinePath; projectCreateInformation.ProjectBasePath = oldProjectPath; - string combineLocation = Path.Combine(projectCreateInformation.CombinePath, newCombineName + ".sln"); + string combineLocation = Path.Combine(projectCreateInformation.CombinePath, newCombineName + ".sln"); // Save combine if (File.Exists(combineLocation)) { diff --git a/src/Main/Base/Project/Src/Internal/Templates/Project/ProjectDescriptor.cs b/src/Main/Base/Project/Src/Internal/Templates/Project/ProjectDescriptor.cs index 70555d31c4..c8a148f5fc 100644 --- a/src/Main/Base/Project/Src/Internal/Templates/Project/ProjectDescriptor.cs +++ b/src/Main/Base/Project/Src/Internal/Templates/Project/ProjectDescriptor.cs @@ -78,7 +78,7 @@ namespace ICSharpCode.SharpDevelop.Internal.Templates string language = languageName != null && languageName.Length > 0 ? languageName : defaultLanguage; LanguageBindingDescriptor descriptor = LanguageBindingService.GetCodonPerLanguageName(language); - ILanguageBinding languageinfo = descriptor.Binding; + ILanguageBinding languageinfo = (descriptor != null) ? descriptor.Binding : null; if (languageinfo == null) { StringParser.Properties["type"] = language; diff --git a/src/Main/Base/Project/Src/Services/ProjectService/ParseableFileContentEnumerator.cs b/src/Main/Base/Project/Src/Services/ProjectService/ParseableFileContentEnumerator.cs index 6aaa394687..c365d595cc 100644 --- a/src/Main/Base/Project/Src/Services/ProjectService/ParseableFileContentEnumerator.cs +++ b/src/Main/Base/Project/Src/Services/ProjectService/ParseableFileContentEnumerator.cs @@ -16,8 +16,15 @@ using ICSharpCode.SharpDevelop.Gui; namespace ICSharpCode.SharpDevelop.Project { /// - /// Description of ParseableFileContentEnumerator. + /// An enumerator which enumerates through a list of project items, returning the + /// parseable file content of each item. /// + /// + /// This class is thread-safe in a very limited way: + /// It can be created from every thread, but may be only used by the thread that created it. + /// It automatically uses WorkbenchSingleton.SafeThreadCall for reading currently open + /// files when it is created/accessed from a thread. + /// public class ParseableFileContentEnumerator : IEnumerator> { void IEnumerator.Reset() { @@ -55,11 +62,13 @@ namespace ICSharpCode.SharpDevelop.Project } ProjectItem[] projectItems; + bool isOnMainThread; public ParseableFileContentEnumerator(IProject project) : this(project.Items.ToArray()) { } public ParseableFileContentEnumerator(ProjectItem[] projectItems) { + isOnMainThread = !WorkbenchSingleton.InvokeRequired; this.projectItems = projectItems; Properties textEditorProperties = ((Properties)PropertyService.Get("ICSharpCode.TextEditor.Document.Document.DefaultDocumentAggregatorProperties", new Properties())); getParseableContentEncoding = Encoding.GetEncoding(textEditorProperties.Get("Encoding", 1252)); @@ -77,8 +86,6 @@ namespace ICSharpCode.SharpDevelop.Project string GetParseableFileContent(IProject project, string fileName) { - //Console.WriteLine("Reading {0} from disk", fileName); - // Loading the source files is done asynchronously: // While one file is parsed, the next is already loaded from disk. string res = project.GetParseableFileContent(fileName); @@ -141,21 +148,35 @@ namespace ICSharpCode.SharpDevelop.Project string GetFileContent(ProjectItem item) { string fileName = item.FileName; + string content; + if (isOnMainThread) + content = GetFileContentFromOpenFile(fileName); + else + content = (string)WorkbenchSingleton.SafeThreadCall(this, "GetFileContentFromOpenFile", fileName); + if (content != null) + return content; + return GetParseableFileContent(item.Project, fileName); + } + + string GetFileContentFromOpenFile(string fileName) + { IWorkbenchWindow window = FileService.GetOpenFile(fileName); if (window != null) { IViewContent viewContent = window.ViewContent; IEditable editable = viewContent as IEditable; if (editable != null) { - //Console.WriteLine("Reading {0} from editable", fileName); return editable.Text; } } - return GetParseableFileContent(item.Project, fileName); + return null; } bool CanReadAsync(ProjectItem item) { - return !FileService.IsOpen(item.FileName); + if (isOnMainThread) + return !FileService.IsOpen(item.FileName); + else + return !(bool)WorkbenchSingleton.SafeThreadCall(typeof(FileService), "IsOpen", item.FileName); } } } diff --git a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/TextEditorDisplayBinding.cs b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/TextEditorDisplayBinding.cs index 8a47a2f858..af46346d72 100644 --- a/src/Main/Base/Project/Src/TextEditor/Gui/Editor/TextEditorDisplayBinding.cs +++ b/src/Main/Base/Project/Src/TextEditor/Gui/Editor/TextEditorDisplayBinding.cs @@ -429,18 +429,14 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor } } - delegate void ParseInformationDelegate(ParseInformation parseInfo); - public void ParseInformationUpdated(ParseInformation parseInfo) { if (textAreaControl.TextEditorProperties.EnableFolding) { - TextArea textArea = textAreaControl.ActiveTextAreaControl.TextArea; - if (textArea.IsHandleCreated) - textArea.Invoke(new ParseInformationDelegate(ParseInformationUpdatedInternal), new object[] { parseInfo }); + WorkbenchSingleton.SafeThreadAsyncCall(this, "ParseInformationUpdatedInvoked", parseInfo); } } - void ParseInformationUpdatedInternal(ParseInformation parseInfo) + void ParseInformationUpdatedInvoked(ParseInformation parseInfo) { try { textAreaControl.Document.FoldingManager.UpdateFoldings(TitleName, parseInfo);