Reputation: 181
WPF Application, C#, MVVM pattern.
My application watches a folder on the network. When a file gets created in that folder I want to parse the data from the file and store the parsed information in a collection. Then move the original file to another folder on the network. My problem is that I cannot move the parsed file from the thread watching the folder to the thread with the collection and the UI. My latest attempt was to try a delegate, but I don't think I have that right.
private ObservableCollection<TestFile> destinationFiles=new ObservableCollection<TestFile>();
public string DestinationFolder
{
get { return destinationFolder; }
set
{
if (destinationFolder != value)
{
destinationFolder = value;
UpdateFileList("Destination");
}
RaisePropertyChanged();
}
}
public MainWindowViewModel()
{
watcher.NotifyFilter = NotifyFilters.LastWrite;
watcher.Created += new FileSystemEventHandler(OnCreated);
watcher.Changed += new FileSystemEventHandler(OnChanged);
}
public delegate void GetFileDelegate(string str);
public void OnCreated(object sender, FileSystemEventArgs e)
{
string name = e.FullPath;
GetFileDelegate del = new GetFileDelegate(GetFile);
Dispatcher.CurrentDispatcher.Invoke(del, name);
}
public void GetFile(string name)
{
TestFile tst = new TestFile(name);
FileName = name;
DestinationFiles.Add(tst); //Here is the exception!
}
The mainwindowviewmodel sets up the FileSystemWatcher. Code for selecting folders and all of that has been left out for brevity, but the constructor is complete as shown.
This runs to the point of updating the Collection: DestinationFiles.Add(tst). Here the exception is thrown for trying to update the collection from a thread different from the Dispatcher thread.
The FileSystemWatcher does not have a "ReportProgress" method as the Background worker has. So I cannot pass back the file through that. I have found a few "examples" showing how to update the UI from the FileSystemWatcher. None found were newer than 2012. Those found did not include code examples that would compile. Others found ignored the WPF and MVVM part of the search string.
Upvotes: 0
Views: 769
Reputation: 7325
Use Application.Current.Dispatcher
instead of Dispatcher.CurrentDispatcher
See the difference: Dispatcher.CurrentDispatcher vs. Application.Current.Dispatcher
Upvotes: 1
Reputation: 3827
When you call Dispatcher.CurrentDispatcher
you're using the current worker thread. In order to make the call on the UI thread in WPF you should use instead:
Application.Current.Dispatcher.Invoke(del, name);
Upvotes: 0