如何在 GUI 事件中访问在 System.Timers.Timer 中创建的对象

本文关键字:Timer 创建 对象 Timers 访问 GUI 事件 System | 更新日期: 2023-09-27 18:33:55

我使用System.Timers.Timer每 N 秒获取一次PrintQueueCollection,因此如果发生更改,我始终保持最新状态。计时器使用打印队列发送一个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 对象的最佳方式是什么,哪个线程是该对象的所有者?

如何在 GUI 事件中访问在 System.Timers.Timer 中创建的对象

您不应该在创建对象时的不同线程中使用对象(与 Windows 功能相关)。在Row_DoubleClick函数中,只需再调用一次 GetPrintQueues 方法并找到您感兴趣的方法。