/// <summary> /// sets up a single feed thread for feeding a cell on [i][j] /// </summary> /// <param name="dataContext"></param> /// <param name="i"></param> /// <param name="j"></param> /// <returns></returns> private Thread SetupFeedThread(MainWindowDataContext dataContext, int i, int j) { var thr = new Thread(async() => { while (!isClosing) { var delayTime = random.Next(1000); await Task.Delay(delayTime); try { dataContext.FirstBuffer[i][j]++; } catch (Exception) { // Occasionally the List2DView.cs errors out on e.g. line 89, sees rows as empty while the Thread assumes a row is available. // In this case, just ignore the update. } // Dispatcher.Invoke(() => gridTopLeft.GetBindingExpression(ItemsControl.ItemsSourceProperty).UpdateTarget()); } }); return(thr); }
static App() { var appSettings = ConfigurationManager.AppSettings; _clientApp = PublicClientApplicationBuilder .Create(ClientId).WithRedirectUri("https://login.microsoftonline.com/common/oauth2/nativeclient") .Build(); _workEntryDataContext = new MainWindowDataContext(); _jiraClient = Jira.CreateRestClient(ConfigurationManager.AppSettings["JiraDomain"], ConfigurationManager.AppSettings["JiraEmail"], ConfigurationManager.AppSettings["JiraToken"]); }
/// <summary> /// Show progress/busy indicator /// </summary> /// <param name="showBusyIndicator">Pass <code>true</code> to show indicator. <code>false</code> to hide it.</param> protected void ShowBusyIndicator(bool showBusyIndicator) { if (Dispatcher != null) { Dispatcher.BeginInvoke((Action)(delegate { MainWindowDataContext.SetBusyIndicator(showBusyIndicator); })); } }
/// <summary> /// Show progress/busy indicator with text /// </summary> /// <param name="busyIndicatorText">Text to display on Busy Indicator.</param> protected void ShowBusyIndicator(string busyIndicatorText) { if (Dispatcher != null) { Dispatcher.BeginInvoke((Action)(delegate { MainWindowDataContext.SetBusyIndicator(true, busyIndicatorText); })); } }
/// <summary> /// Sets up 9 feed threads. One for each cell. /// </summary> /// <param name="dataContext"></param> private void SetupFeedThreads(MainWindowDataContext dataContext) { for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { Thread thread = SetupFeedThread(dataContext, i, j); thread.Start(); } } }
/// <summary> /// Constructor. /// Setup the Buffers with default (1) data. /// Setup the Feed threads /// </summary> public MainWindow() { InitializeComponent(); // TODO: should be in a separate DataContext; var datacontext = new MainWindowDataContext(); DataContext = datacontext; datacontext.FirstBuffer.Add(new System.Collections.ObjectModel.ObservableCollection <int>(new List <int> { 1, 1, 1 })); datacontext.FirstBuffer.Add(new System.Collections.ObjectModel.ObservableCollection <int>(new List <int> { 1, 1, 1 })); datacontext.FirstBuffer.Add(new System.Collections.ObjectModel.ObservableCollection <int>(new List <int> { 1, 1, 1 })); datacontext.SecondBuffer.Add(new System.Collections.ObjectModel.ObservableCollection <int>(new List <int> { 1, 1, 1 })); datacontext.SecondBuffer.Add(new System.Collections.ObjectModel.ObservableCollection <int>(new List <int> { 1, 1, 1 })); datacontext.SecondBuffer.Add(new System.Collections.ObjectModel.ObservableCollection <int>(new List <int> { 1, 1, 1 })); datacontext.ThirdBuffer.Add(new System.Collections.ObjectModel.ObservableCollection <int>(new List <int> { 1, 1, 1 })); datacontext.ThirdBuffer.Add(new System.Collections.ObjectModel.ObservableCollection <int>(new List <int> { 1, 1, 1 })); datacontext.ThirdBuffer.Add(new System.Collections.ObjectModel.ObservableCollection <int>(new List <int> { 1, 1, 1 })); // Wait for the Observable Collection and window to be ready. Threads were started whilst the window was still being setup. // Let's not be too eager. Loaded += (o, s) => { SetupFeedThreads(datacontext); SetupSwapThread(datacontext); // now for some unsafe fun! 9 threads incrementing a single integer (on random intervals). // I will increment a safe integer as well to better show off the differences. SetupUnsafeThreads(datacontext); }; }
/// <summary> /// Setup some unsafe threads, showing of importance of critical sections whenever threads use the same memory address/variable. /// </summary> /// <param name="dataContext"></param> private void SetupUnsafeThreads(MainWindowDataContext dataContext) { for (int i = 0; i < 9; i++) { Thread thread = new Thread(() => { // NOTE: this will cause unexpected behavior should UnsafeCounter or SafeCounter try to increment past int.MaxValue. // Since the program does not crash, I am fine with this, since the use of this is to show off Thread unsafety/critical sections. while (!isClosing) { dataContext.UnsafeCounter++; dataContext.IncrementSafeCounter(); } }); thread.Start(); } }
/// <summary> /// Thread for swapping the buffers. /// Idea is to always have the latest version of data (as time of swapping) available in the third buffer, /// where the second buffer will have the second to last version of the data. /// </summary> /// <param name="datacontext"></param> private void SetupSwapThread(MainWindowDataContext dataContext) { Thread swapThread = new Thread(async() => { while (!isClosing) { await Task.Delay(5000); // So.. // FirstBuffer = "live" data. // SecondBuffer = 2nd most recent snapshot // ThirdBuffer = most recent snapshot. // So, swap second with third and third with first // e.g situation: // 1st = 4, 2nd = 2, 3rd = 3 // after first swap: // 1st = 4, 2nd = 3, 3rd = 2 // after 2nd swap: // 1st = 2, 2nd = 3, 3rd = 4 // Assuming live updates won't stop, 1st should be updated to the most recent version rather quickly. // possible solution is to copy the 3rd after the swap and then replacing 1st. May cause 1st to lose newer data though. // Hmm, refreshing is a bit wonky, which is unfortunate. It seems like the data takes a bit of time to update. var temp = dataContext.SecondBuffer; dataContext.SecondBuffer = dataContext.ThirdBuffer; dataContext.ThirdBuffer = temp; var temp2 = dataContext.ThirdBuffer; dataContext.ThirdBuffer = dataContext.FirstBuffer; dataContext.FirstBuffer = temp2; dataContext.OnPropertyChanged(nameof(dataContext.FirstBuffer)); dataContext.OnPropertyChanged(nameof(dataContext.SecondBuffer)); dataContext.OnPropertyChanged(nameof(dataContext.ThirdBuffer)); } }); swapThread.Start(); }
public MainWindow() { InitializeComponent(); this.dataContext = new MainWindowDataContext(this); this.Icon = MoonPdf.Resources.moon.ToBitmapSource(); this.DataContext = dataContext; this.UpdateTitle(); moonPdfPanel.ViewTypeChanged += moonPdfPanel_ViewTypeChanged; moonPdfPanel.ZoomTypeChanged += moonPdfPanel_ZoomTypeChanged; moonPdfPanel.PageRowDisplayChanged += moonPdfPanel_PageDisplayChanged; moonPdfPanel.PdfLoaded += moonPdfPanel_PdfLoaded; moonPdfPanel.PasswordRequired += moonPdfPanel_PasswordRequired; this.UpdatePageDisplayMenuItem(); this.UpdateZoomMenuItems(); this.UpdateViewTypeItems(); this.Loaded += MainWindow_Loaded; }
public FindAddIssueCommand(MainWindowDataContext dataContext) { _dataContext = dataContext; }
public MainWindow() { InitializeComponent(); MWDC = new MainWindowDataContext(); this.DataContext = this.MWDC; }
public FetchEventsCommand(MainWindowDataContext dataContext) { _dataContext = dataContext; }
protected void SetCurrentViewModel(ViewModelBase viewModel) { MainWindowDataContext.SetCurrentViewModel(viewModel); viewModel.Dispatcher = Dispatcher; }
public MainWindow() { InitializeComponent(); DataContext = new MainWindowDataContext(); }
public CopyToClipboardCommand(MainWindowDataContext dataContext) { _dataContext = dataContext; }
public FetchIssuesCommand(MainWindowDataContext workEntryDataContext) { _dataContext = workEntryDataContext; }
public SaveEntriesCommand(MainWindowDataContext dataContext) { _dataContext = dataContext; }