public void DoWorkAfter_should_execute_the_work_after_given_duration() { DateTime workStartedAt = default(DateTime); DateTime workCompletedAt = default(DateTime); DateTime countDownStartedAt = default(DateTime); TimeSpan waitDuration = TimeSpan.FromSeconds(2); TimeSpan howLongWorkTakes = TimeSpan.FromSeconds(1); TimeSpan timeout = waitDuration.Add(howLongWorkTakes.Add(TimeSpan.FromMilliseconds(500))); DispatcherFrame frame = default(DispatcherFrame); "Given no parallel work running".Context(() => { Assert.False(ParallelWork.IsAnyWorkRunning()); frame = new DispatcherFrame(); workStartedAt = default(DateTime); workCompletedAt = default(DateTime); }); "When Start.Work().RunAfter() is called".Do(() => { Start.Work(() => { workStartedAt = DateTime.Now; Thread.Sleep(howLongWorkTakes); }) .OnComplete(() => { workCompletedAt = DateTime.Now; frame.Continue = false; }) .RunAfter(waitDuration); countDownStartedAt = DateTime.Now; }); "It should not start the work until the duration has elapsed".Assert(() => { Assert.Equal(default(DateTime), workStartedAt); Assert.Equal(default(DateTime), workCompletedAt); Assert.True(WaitForWorkDoneAndFireCallback(timeout, frame)); }); "It should start the work after duration has elapsed".Assert(() => { Assert.True(WaitForWorkDoneAndFireCallback(timeout, frame)); // Work should start within 500ms of start time DateTime expectedStartTime = countDownStartedAt.Add(waitDuration); Assert.InRange(workStartedAt, expectedStartTime, expectedStartTime.AddMilliseconds(500)); // Work should end within 500ms of expected end time DateTime expectedEndTime = countDownStartedAt.Add(waitDuration).Add(howLongWorkTakes); Assert.InRange(workCompletedAt, expectedEndTime, expectedEndTime.AddMilliseconds(500)); }); }
private void SaveAndRefreshDiagram() { if (DesignerProperties.GetIsInDesignMode(this)) { return; } if (this.CurrentDiagram == default(DiagramFile)) { return; } _RefreshDiagramTimerStarted = false; var diagramFileName = this.CurrentDiagram.DiagramFilePath; var pathForContentEditor = ContentEditor.Tag as string; if (diagramFileName != pathForContentEditor) { MessageBox.Show(Window.GetWindow(this), "Aha! This is one of those weird race condition I am getting into." + Environment.NewLine + "Close the app and start again", "Weird race condition", MessageBoxButton.OK, MessageBoxImage.Error); return; } // Take a backup if this is the first time the diagram being modified // after opening if (_FirstSaveAfterOpen) { File.Copy(diagramFileName, diagramFileName.Replace(new FileInfo(diagramFileName).Extension, ".bak"), true); _FirstSaveAfterOpen = false; } var content = ContentEditor.Text; this.CurrentDiagram.Content = content; OnBeforeSave(this.CurrentDiagram); string plantUmlPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Thirdparty\\plantuml.exe"); if (!File.Exists(plantUmlPath)) { MessageBox.Show(Window.GetWindow(this), "Cannot find file: " + Environment.NewLine + plantUmlPath, "PlantUml.exe not found", MessageBoxButton.OK, MessageBoxImage.Error); return; } if (ParallelWork.IsAnyWorkRunning()) { return; } Start.Work(() => { // Save the diagram content using UTF-8 encoding to support // various international characters, which ASCII won't support // and Unicode won't make it cross platform File.WriteAllText(diagramFileName, content, Encoding.UTF8); // Use plantuml to generate the graph again using (var process = new Process()) { var startInfo = new ProcessStartInfo(); startInfo.FileName = plantUmlPath; startInfo.Arguments = "-charset UTF-8 -graphvizdot \"" + Settings.Default.GraphVizLocation + "\" \"" + diagramFileName + "\""; startInfo.WindowStyle = ProcessWindowStyle.Hidden; // OMAR: Trick #5 startInfo.CreateNoWindow = true; // OMAR: Trick #5 process.StartInfo = startInfo; if (process.Start()) { process.WaitForExit(10000); } } }) .OnComplete(() => { BindingOperations.GetBindingExpression(DiagramImage, Image.SourceProperty).UpdateTarget(); OnAfterSave(this.CurrentDiagram); }) .OnException((exception) => { OnAfterSave(this.CurrentDiagram); MessageBox.Show(Window.GetWindow(this), exception.Message, "Error running PlantUml", MessageBoxButton.OK, MessageBoxImage.Error); }) .Run(); }