У меня проблема. Я сделал сервис, который отслеживает задания на печать в режиме реального времени. Это не сработало идеально, но у меня не было больших проблем. Теперь мне нужно сменить службу на программу Windows Forms. И у меня проблема с темами.
Ошибка:
System.InvalidOperationException: 'Вызывающий поток не может получить доступ к этому объекту, потому что другой поток владеет им.'
Эта ошибка появляется в строке "PrintQueue.Refresh ()".
Я не могу найти, где пытается запустить другой поток.
Я попытался установить другой поток и запустить его с помощью процедуры MonitoringJobs (), но он не работает.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Collections.Concurrent;
using System.Data.SqlClient;
using System.Diagnostics;
using System.ServiceProcess;
using System.Management;
using System.Windows;
using System.Printing;
using System.Configuration;
using System.Collections.Specialized;
using System.Threading;
namespace MonitoringPrintJobs
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
timer.Elapsed += GetJobs;
timer.AutoReset = true;
timer.Enabled = true;
}
System.Timers.Timer timer = new System.Timers.Timer(5);
int writeInterval = 1000;
int DefaultWriteInterval = 1000;
bool Logging;
SelectPrinter fSelectPrinter = new SelectPrinter();
ConcurrentDictionary<string, string> QueueJobs = new ConcurrentDictionary<string, string>();//declaration printers jobs dictionary
ConcurrentDictionary<string, DateTime> PrintedJobs = new ConcurrentDictionary<string, DateTime>();
PrintServer printServer = null;
PrintQueueCollection QueuesOnLocalServer = null;
List<PrintQueue> queues = new List<PrintQueue>();
public void MonitoringJobs()
{
//if(queues != null)
foreach (var PrintQueue in queues)
{
PrintQueue.Refresh();
using (var jobs = PrintQueue.GetPrintJobInfoCollection())//wait until collection updates!!!
foreach (var job in jobs)
{
if (!QueueJobs.ContainsKey(job.Name))//if list with printer jobs doesn't contain found job (name)
{//then put name in list with printer jobs
QueueJobs.TryAdd(job.Name, job.JobStatus.ToString());
if (Logging == true)
{
File.AppendAllText(@"D:\Logs\Logging.txt", String.Format("{0} - {1} - {2}{3}", DateTime.Now, job.Name, job.JobStatus, Environment.NewLine));
}
}
else//if list with printer jobs contains found job name
{
if (QueueJobs[job.Name] != job.JobStatus.ToString() && !QueueJobs[job.Name].ToLower().Contains("error"))//if status for this job doesn't exist
{
QueueJobs[job.Name] = job.JobStatus.ToString();//replace job's status
if (Logging == true)
{
File.AppendAllText(@"D:\Logs\Logging.txt", String.Format("{0} - {1} - {2}{3}", DateTime.Now, job.Name, job.JobStatus, Environment.NewLine));
}
}
if (job.JobStatus.ToString().ToLower().Contains("error") && PrintedJobs.ContainsKey(job.Name))
{
var someVar = new DateTime();
PrintedJobs.TryRemove(job.Name, out someVar);
}
}
if (QueueJobs[job.Name].ToLower().Contains("print") && !QueueJobs[job.Name].ToLower().Contains("error"))//if successfully printed
{
PrintedJobs.TryAdd(job.Name, DateTime.Now);
}
}
}
}
private void GetJobs(Object source, System.EventArgs e)
{
writeInterval--;
MonitoringJobs();
if (writeInterval <= 0)
{
writeInterval = DefaultWriteInterval;
PrintedJobs.Clear();
QueueJobs.Clear();
}
}
protected void OnStart()
{
QueuesOnLocalServer = printServer.GetPrintQueues();
writeInterval = 120000;
foreach (var item in fSelectPrinter.SelectetPrinters)
Logging = true;
foreach (var printer in fSelectPrinter.SelectetPrinters)
{
if (string.IsNullOrEmpty(printer))
{
timer.Stop();
Environment.Exit(0);
}
var queue = QueuesOnLocalServer.FirstOrDefault(o => o.FullName.ToUpper() == printer.ToUpper());
if (queue == null)
{
timer.Stop();
Environment.Exit(0);
}
queues.Add(queue);
}
timer.Start();
}
private void button2_Click(object sender, EventArgs e)
{
fSelectPrinter.ShowDialog();
}
private void Form1_Load(object sender, EventArgs e)
{
printServer = new PrintServer();
foreach (PrintQueue pq in printServer.GetPrintQueues())
fSelectPrinter.listBox1.Items.Add(pq.Name);
}
private void button1_Click_1(object sender, EventArgs e)
{
bool StartPrinting = button2.Enabled = false;//turn of select printers form button
if (StartPrinting == false)//StartPrinting == monitoring == true
{
OnStart();
}
else
{
StartPrinting = true;//StartPrinting == monitoring == false
timer.Stop();
}
}
}
}
В этой программе я пытался получить статусы заданий на печать и вывести их в listbox1 и записать результаты со строкой. Формат в файле.