代码之家  ›  专栏  ›  技术社区  ›  poke

将文本分配给文本字段时出现InvalidOperationException

  •  5
  • poke  · 技术社区  · 15 年前

    我对C有个奇怪的问题,我还不能解释。实际上,我计划创建一个简单的文件查看器,在文件发生更改时自动更新显示的文本,但结果比我想象的要复杂。

    我有以下基本代码:

    public partial class Main : Window
    {
        private FileSystemWatcher watcher;
        private String filePath = "C:\\";
        private String fileName = "example.txt";
    
        public Main()
        {
            InitializeComponent();
    
            this.txtFile.Text = File.ReadAllText(filePath + fileName);
    
            this.watcher = new FileSystemWatcher(filePath);
            this.watcher.Changed += new FileSystemEventHandler(watcher_Changed);
            this.watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite;
            this.watcher.Filter = fileName;
            this.watcher.EnableRaisingEvents = true;
        }
    
        void watcher_Changed(object sender, FileSystemEventArgs e)
        {
            String text = File.ReadAllText(e.FullPath);
            this.txtFile.Text = text; // <-- here comes the exception (line 42)
        }
    }
    

    System.InvalidOperationException 异常,告诉我对象已在其他线程中使用。那么,为什么我会得到这个例外,更重要的是,我必须做什么,使这个工作?

    编辑

    顺便说一下,不管我分配的字符串是什么,我都会得到异常。

    编辑2

    例外情况的全文(德语):

    System.InvalidOperationException wurde nicht behandelt.
      Message="Der aufrufende Thread kann nicht auf dieses Objekt zugreifen, da sich das Objekt im Besitz eines anderen Threads befindet."
      Source="WindowsBase"
      StackTrace:
           bei System.Windows.Threading.Dispatcher.VerifyAccess()
           bei System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
           bei System.Windows.Controls.TextBox.set_Text(String value)
           bei LiveTextViewer.Main.watcher_Changed(Object sender, FileSystemEventArgs e) in ...\Main.xaml.cs:Zeile 42.
           bei System.IO.FileSystemWatcher.CompletionStatusChanged(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* overlappedPointer)
           bei System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
      InnerException:
    
    1 回复  |  直到 15 年前
        1
  •  6
  •   Martin Niederl    9 年前

    您需要使用Dispatcher将设置文本的调用推送到UI线程上:

    void watcher_Changed(object sender, FileSystemEventArgs e)
    {
        String text = File.ReadAllText(e.FullPath);
    
        this.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() => 
            {
                 this.txtFile.Text = text;
                 // Do all UI related work here...
            }));
    }