internal async Task <bool> AsynchronousBreak(RemoteBreakpointInfo info) { using SemaphoreSlim semaphore = new SemaphoreSlim(0, 1); void resumeHandler(object sender, EventArgs e) { semaphore.Release(); } await Dispatcher.UIThread.InvokeAsync(() => { EditorControl.ActiveBreakpoint = info.BreakpointSpan.Start - PreSource.Length - 1; EditorControl.SetSelection(info.BreakpointSpan.End - PreSource.Length - 1, 0); BreakpointPanel.SetContent(info); BreakpointPanel.ResumeClicked += resumeHandler; this.FindAncestorOfType <Window>().Closing += resumeHandler; OpenSidePanel(); }); await semaphore.WaitAsync(); bool tbr = false; await Dispatcher.UIThread.InvokeAsync(() => { tbr = BreakpointPanel.IgnoreFurtherOccurrences; CloseSidePanel(); BreakpointPanel.ResumeClicked -= resumeHandler; this.FindAncestorOfType <Window>().Closing -= resumeHandler; EditorControl.ActiveBreakpoint = -1; }); semaphore.Dispose(); return(tbr); }
/// <summary> /// A function to handle breakpoints in synchronous methods. Pass this as an argument to <see cref="Compile(Func{BreakpointInfo, bool}, Func{BreakpointInfo, Task{bool}})"/>. To prevent deadlocks, this function will have no effect if called from the UI thread. /// </summary> /// <param name="info">A <see cref="BreakpointInfo"/> object containing information about the location of the breakpoint and the current value of local variables.</param> /// <returns><see langword="true" /> if further occurrences of the same breakpoint should be ignored; <see langword="false"/> otherwise.</returns> public bool SynchronousBreak(BreakpointInfo info) { if (!CheckAccess()) { EventWaitHandle waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset); bool tbr = false; async void resumeHandler(object sender, EventArgs e) { await Dispatcher.UIThread.InvokeAsync(() => tbr = BreakpointPanel.IgnoreFurtherOccurrences); waitHandle.Set(); } Dispatcher.UIThread.InvokeAsync(() => { EditorControl.ActiveBreakpoint = info.BreakpointSpan.Start - PreSource.Length - 1; EditorControl.SetSelection(info.BreakpointSpan.End - PreSource.Length - 1, 0); BreakpointPanel.SetContent(info); BreakpointPanel.ResumeClicked += resumeHandler; this.FindAncestorOfType <Window>().Closing += resumeHandler; OpenSidePanel(); }); waitHandle.WaitOne(); Dispatcher.UIThread.InvokeAsync(() => { CloseSidePanel(); BreakpointPanel.ResumeClicked -= resumeHandler; this.FindAncestorOfType <Window>().Closing -= resumeHandler; EditorControl.ActiveBreakpoint = -1; }); return(tbr); } else { return(false); } }
private async Task Initialize(string sourceText, string preSource, string postSource, IEnumerable <CachedMetadataReference> references, CSharpCompilationOptions compilationOptions, string guid, Shortcut[] additionalShortcuts) { this.CompilationOptions = compilationOptions; this.Guid = guid; EditorControl = this.FindControl <CSharpSourceEditorControl>("EditorControl"); await EditorControl.SetText(sourceText); this.PreSource = preSource; this.PostSource = postSource; OriginalText = EditorControl.Text.ToString(); OriginalDocument = EditorControl.Document; LastSavedText = OriginalText; OriginalTimeStamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); CompletionService service = CompletionService.GetService(OriginalDocument); this.FindControl <CompletionWindow>("CompletionWindow").Document = OriginalDocument; this.FindControl <CompletionWindow>("CompletionWindow").CompletionService = service; this.CompletionWindow = this.FindControl <CompletionWindow>("CompletionWindow"); this.MethodOverloadList = this.FindControl <MethodOverloadList>("MethodOverloadList"); this.FindControl <MethodOverloadList>("MethodOverloadList").Document = OriginalDocument; this.FindControl <CompletionWindow>("CompletionWindow").Committed += CompletionCommitted; StatusBar = this.FindControl <StatusBar>("StatusBar"); ErrorContainer = this.FindControl <ErrorContainer>("ErrorContainer"); ReferencesContainer = this.FindControl <ReferencesContainer>("ReferencesContainer"); SaveHistoryContainer = this.FindControl <SaveHistoryContainer>("SaveHistoryContainer"); SettingsContainer = new SettingsContainer(additionalShortcuts) { Margin = new Thickness(10, 0, 0, 10), IsVisible = false }; Grid.SetRow(SettingsContainer, 2); this.FindControl <Grid>("ContainerGrid").Children.Add(SettingsContainer); await this.SetReferences(ImmutableList.Create((from el in references select(MetadataReference) el).ToArray())); EditorControl.ClearUndoStack(); this.CompilationErrorChecker = CompilationErrorChecker.Attach(this); this.SymbolToolTip = this.FindControl <SymbolToolTip>("SymbolToolTip"); this.SymbolToolTip.References = References; this.BreakpointPanel = this.FindControl <BreakpointPanel>("BreakpointPanel"); string autosaveDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), Assembly.GetEntryAssembly().GetName().Name); Directory.CreateDirectory(Path.Combine(autosaveDirectory, Guid)); AutoSaveFile = Path.Combine(autosaveDirectory, Guid, "autosave_" + System.Guid.NewGuid().ToString("N") + ".cs"); SaveDirectory = Path.Combine(autosaveDirectory, Guid); this.AutoSaver = AutoSaver.Start(this, AutoSaveFile); InputHandler = new InputHandler(this, EditorControl, this.FindControl <CompletionWindow>("CompletionWindow"), this.FindControl <MethodOverloadList>("MethodOverloadList"), service); EditorControl.ToggleBreakpoint += async(s, e) => { await this.TryToggleBreakpoint(e.LineStart, e.LineEnd); }; }