我已经设置了一个在对象实例上运行的WCF主机。从WCF客户端调用以下方法时,将抛出错误“调用线程无法访问此对象,因为不同的线程拥有它”。
public List<PrintQueueData> getPrintQueues()
{
List<PrintQueueData> resultQueues = new List<PrintQueueData>();
List<PrintQueue> queues = queueCollection;
foreach (PrintQueue q in queues)
{
// This throws an exception
resultQueues.Add(new PrintQueueData(q.HostingPrintServer.ToString(), q.Name));
// This does NOT throw any exceptions
resultQueues.Add(new PrintQueueData("1", "2");
}
return resultQueues;
}
我该怎么做才能纠正这个错误?
编辑:queueCollection是包含此方法的类的字段。
编辑:queueCollection在此类的开头声明,它的类型是printqueue列表,与此方法中分配的内容相同。
编辑:我有一个运行的计时器使用了queueCollection,但是,我将Timer.Enabled设置为false并且错误仍然发生。
答案 0 :(得分:1)
“PrintQueue”类型的行为类似于“DependencyObject”。它绑定到当前线程的“Dispatcher”,类似于WPF中的UI元素。这种方式你不能在与创建队列的线程不同的线程上使用它。您必须缓存“PrintQueueData”对象(而不是“PrintQueue”对象)或在每次方法调用时实例化“PrintQueue”。
您获得的实际异常来自“System.Windows.Threading.Dispatcher.VerifyAccess()”,由“System.Printing.PrintQueue.VerifyAccess()”调用。无论何时访问属性或打印队列的方法,都会调用后者。
答案 1 :(得分:0)
你可以试试List<PrintQueue> queues = queueCollection.ToList();
或沿着这条线的东西。您想要实现的是快速创建queueCollection
的副本。这应该减少队列被其他线程“锁定”的可能性,从而导致所述错误。
或者,您可以在访问queueCollection
时尝试使用同步。例如:
lock (wantMyQueue)
{
// Access queueCollection in here
}
其中wantMyQueue
是一个简单的object
全局变量。