即使同一个线程卡在模态窗口上,CPU也会调用一个动作?

时间:2015-05-05 14:02:40

标签: c# wpf multithreading modal-dialog begininvoke

问题:

BeginInvoke在主线程上执行代码,而此线程也卡在模态窗口上。

代码:[附在下面]

  • 我有一个按钮,其“点击”打开FolderBrowserDialog窗口
  • 我有fileWatcherSystem来监视文件。
  • “onChanged”方法是在更改文件时调用的方法。 [它在另一个线程上调用]
  • 在“onChanged”中我使用beginInvoke调用主UI线程上的函数,此函数显示一个messageBox。

流程:

  1. 当应用程序启动时,它会使用FileSystemWatcher
  2. 开始观看某个文件
  3. 稍后,用户点击按钮,应用程序将打开“FolderBrowserDialog”窗口(此窗口为模态)
  4. FolderBrowserDialog“窗口仍处于打开状态(模态)时,用户使用外部编辑器更改监视文件[例如,记事本]
  5. 调用OnChanged回调并执行System.Windows.Application.Current.Dispatcher.BeginInvoke (new Action(() => showMsg()));以在仍然停留在模态对话框上的主线程上调用showMsg。
  6. 问题:

    showMsg在主线程上被调用,虽然它仍然卡在FolderBrowserDialog上,它仍然是开放的和模态的。

    问题:

    为什么showMsg立即被调用而不是FolderBrowserDialog关闭后(用户选择文件夹后)?我希望在模式对话框关闭时调用showMsg。

    任何想法都会受到赞赏,非常感谢!!

    MainWindow.CS

    public partial class MainWindow : Window
    {
    
        public MainWindow()
        {
            InitializeComponent();
            int threadIDMain = System.Threading.Thread.CurrentThread.ManagedThreadId;
            CreateFileWatcher(@"C:\temp", @"myFile.txt"); // directory path + file name
        }
    
        private FileSystemWatcher Watcher; 
    
        public void CreateFileWatcher(string directoryPath, string fileName)
        {
            Watcher = new FileSystemWatcher();
            Watcher.Path = directoryPath;
            Watcher.NotifyFilter = NotifyFilters.LastWrite;
            Watcher.Filter = fileName;
            Watcher.Changed += new FileSystemEventHandler(OnChanged);
            Watcher.EnableRaisingEvents = true;
        }
    
        private void OnChanged(object source, FileSystemEventArgs e) // called when the watched file is changed , this is called on a different thread
        {
            int threadIDChanged = System.Threading.Thread.CurrentThread.ManagedThreadId;
            System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() => showMsg())); // calling "showMsg" on main thread
        }
    
        private void showMsg()
        {
            int threadIDshowMsg = System.Threading.Thread.CurrentThread.ManagedThreadId;
            MessageBox.Show("showMsg: Here I am in thread ID: " + threadIDshowMsg); // same thread as main thread
        }
    
    
        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            using (System.Windows.Forms.FolderBrowserDialog dlg = new System.Windows.Forms.FolderBrowserDialog())
            {
                int threadIDClick = System.Threading.Thread.CurrentThread.ManagedThreadId;
    
                dlg.ShowNewFolderButton = true;
                dlg.Description = "Opened from thread Id " + threadIDClick;
                System.Windows.Forms.DialogResult resultFileDialog = dlg.ShowDialog();
                if (resultFileDialog == System.Windows.Forms.DialogResult.OK)
                {
                    //handle this.
                }
            }
        }
    }
    

    XAML:

    <Grid>
        <Button Content="click to open file browser dialog" Height="50"  Click="Button_Click_1"/>
    </Grid>
    

0 个答案:

没有答案