0

I want to show non-modal Information Window and wait for touch of smart card in other thread. I need to block my main UI thread to prevent user actions unless the smart card will be touched with card reader. I do it in main thread so:

InformationWindow infoWindow = new InformationWindow();
infoWindow.tblockInfo.Text = someInfoAboutRequieredAction;
infoWindow.Show();

Semaphore.WaitOne();

infoWindow.Close();

It works fine and is drawn normally in some cases, but my information WPF window is often not fully drawn. There is only Title part and no one control inside window (and background color) is visible as it's hanging

please help, i haven't understood for a week what to do

P.S. I have been tried InvalidateVisual(), UpdateLayout() and Thread.Sleep before Semaphore.WaitOne() but it hasn't helped

  • Try not to block the UI thread and everything should draw fine. Normally for background tasks you would use a 2nd thread but the new async functionality should solve this problem easily. – sprocket12 Aug 27 '13 at 10:33
  • My application is concerned with smart card processing. I need to block my main UI thread to prevent user actions unless the smart card will be touched with card reader (for writing new data on it) – Konstantin Gertsenberger Aug 27 '13 at 10:42
  • ShowDialog() was invented specially for it. Use it and for all background work use Threads/Tasks/BackgroundWorker etc – Alex Zhukovskiy Aug 27 '13 at 10:49
  • yes, thank you, but in this case how can I close this window in other thread when it will finish the processing the smart card touched? and i need to exclude any possability to close this window and next user working without using smart card... – Konstantin Gertsenberger Aug 27 '13 at 11:46

1 Answers1

0

Blocking the Main UI thread is very different to blocking the UI. You would do better to disable the UI (e.g. MainWindow.IsEnabled = false) and leave the UI thread to draw the window.

This would also allow you to add a cancel button to your InformationWindow which can be used in case somebody kicks off this process and doesn't have a smart card to hand.

AlSki
  • 6,868
  • 1
  • 26
  • 39
  • yes, I can block my UI with "MainWindow.IsEnabled = false" but how can I unblock it in my other thread (processing smart card) when it will finish the processing after the user hands the smart card. if I write "((MainWindow)Application.Current.MainWindow).IsEnabled = true" or "((MainWindow)Application.Current.MainWindow).infoWindow.Close()" in other thread it will lead to exception "The calling thread cannot access this object because a different thread owns it" – Konstantin Gertsenberger Aug 27 '13 at 11:44
  • @KonstantinGertsenberger use dispatcher if you're calling from non UI thread – dnr3 Aug 27 '13 at 12:09
  • @dnr3 ok, thank you. I know how to use it. I hope it's a good decision and there is no method to redraw entirely non-modal window before "Semaphore.WaitOne()" in order to show it correctly. – Konstantin Gertsenberger Aug 27 '13 at 12:22
  • @KonstantinGertsenberger, as toerhs have said, do not perform hard-waits, like 'Semaphore.WaitOne()' in the GUI thread. Drawing forms usually means drawing multiple windows and the sending/posting of several messages, which must be handled. – Martin James Aug 27 '13 at 13:46