I am stuck, and I need your help please. I am developing an WPF application that reads data from a database, and stores that data into an ObservableCollecion. The ObservableCollection is bound to a TreeView (HierarchicalDataTemplate) on the UI. This way, when the properties are updated in the ObservableCollection, the UI updates as well. The application needs to do some processing to the data in the background at an exact scheduled time, and for this I decided to use the Quartz.NET. It seems to be very accurate for what I need. My problem is that I cannot figure out how to update the ObservableCollection from the Quartz' IJob class. I am hoping that you can help me by giving me some pointers. The following is the example of my code. I made it as short as possible, and for the purposes of this example I combined all of it within the MainWindow class without following the MVVM pattern.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
this.MyCollection = new ObservableCollection<MyData>();
BindingOperations.CollectionRegistering += BindingOperations_CollectionRegistering;
// Bind TreeView to ObservableCollection MyCollection
myTreeView.ItemsSource = MyCollection;
// I have methods that get data from a DB and populate the ObservableCollection MyCollection
GetDataFromDB();
// Initialize the Quartz.NET scheduler
RunQueuedEvents().GetAwaiter().GetResult();
}
public void BindingOperations_CollectionRegistering(object sender, CollectionRegisteringEventArgs e)
{
if (e.Collection == MyCollection)
{
BindingOperations.EnableCollectionSynchronization(MyCollection, lockMyCollection);
}
}
public ObservableCollection<MyData> MyCollection { get; }
// object used to lock the ObservableCollection MyCollection
private object lockMyCollection = new object();
private async Task RunQueuedEvents()
{
try
{
// Grab the Scheduler instance from the Factory
NameValueCollection props = new NameValueCollection { { "quartz.serializer.type", "binary" } };
StdSchedulerFactory factory = new StdSchedulerFactory(props);
IScheduler scheduler = await factory.GetScheduler();
// Start the Scheduler instance
await scheduler.Start();
// Define the Job
IJobDetail job = JobBuilder.Create<MyJob>()
.WithIdentity("job1", "group1")
.UsingJobData("MyCommand", "DO IT 13423")
.Build();
// Define the Trigger
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("trigger1", "group1")
.StartAt(myStartTime)// some Time I want it to trigger at
.Build();
// Tell Quartz to schedule the Job using our Trigger
await scheduler.ScheduleJob(job, trigger);
}
}
catch (SchedulerException se)
{
}
}
}
My Quartz.NET job looks like the following:
public class MyJob : IJob
{
public string MyCommand { private get; set; }
public async Task Execute(IJobExecutionContext context)
{
await Task.Run(() =>
{
//In here I process the MyCommand
});
// This is where I am stuck now. How do I update the properties within the ObservableCollection, once the Task has finished running.
}
}