我正在使用System.Timers.Timer
每N秒获得一次PrintQueueCollection
所以如果发生变化,我总是保持最新状态。计时器发送一个带有PrintQueue的RefreshEvent
,这样我就可以处理我的Gui中的变化。
这是刷新功能,计时器每隔n秒调用
private void Refresh()
{
lock (_locker)
{
try
{
// _server == ServerName if isNullOrEmppty it's localhost
PrintServer printServer = new PrintServer(_server);
PrintQueueCollection printQueueCollection = printServer.GetPrintQueues();
foreach (PrintQueue pq in printQueueCollection)
{
if (_firstRun) break;
// List of Unique Printernames so not all printers get 'refreshed'
if (_printersToMonitor.Contains(pq.Name))
{
var currentPrinter = new Printer(pq);
// Event catched in Gui
Refreshed?.Invoke(currentPrinter);
}
}
}
catch (Exception)
{
//...
}
}
}
事件以控制方式捕获
// Printer is a Wrapper class that contains the PrintQueue and several other information I need e.g. results of SNMP walks
private void RefreshPrinter(Printer printer)
{
if (_localPrinters.Count == 0)
Dispatcher.Invoke(() => _localPrinters.Add(printer));
else
{
// _localPrinters is a ObservableCollection<Printer> Bound to gui
foreach (Printer p in _localPrinters.ToList())
{
if (p.FullName == printer.FullName)
{
p.NumberOfJobs = printer.NumberOfJobs;
p.Status = printer.Status;
return;
}
}
Dispatcher.Invoke(() => _localPrinters.Add(printer));
}
}
到目前为止,现在非常好,我不知道如何处理。 ObservableCollection<Printer>
绑定到DataGrid
,显示所有常规信息。现在,如果用户双击一行,我想在userControl中显示一些“更深层”的信息。但是我找不到在这里访问PrintQueue
的方法,因为它是错误的线程。
private void Row_DoubleClick(object sender, MouseButtonEventArgs e)
{
// Printer is fine, just the PrintQueue inside is full of System.InvalidOperationException
Printer p = (sender as DataGridRow)?.DataContext as Printer;
UcPrinterDetails.InitializeDetails(p.PrintQueue);
UcPrinterDetails.Visibility = UcPrinterDetails.Visibility != Visibility.Visible ? Visibility.Visible : Visibility.Collapsed;
}
所以我的问题是:访问PrintQueue对象的最佳方法是什么,以及哪个Thread是对象的所有者?
答案 0 :(得分:0)
你不应该在不同的线程中使用对象(与Windows功能相关),然后创建它。 在Row_DoubleClick函数中,只需再调用一次GetPrintQueues方法并找到您感兴趣的方法。