2011-03-11 61 views
0

我已经建立了一个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

“queueCollection”从哪里来? – 2011-03-11 01:16:49

+0

您是在某处使用BackgroundWorker或线程吗? – 2011-03-11 02:54:01

+0

我有一个定时器运行使用queueCollection,但是,我仍然收到错误后设置Timer.Enabled为false。 – mike9182 2011-03-11 14:34:18

回答

0

你可以尝试List<PrintQueue> queues = queueCollection.ToList();或沿着那条线。你想要达到的目的是快速创建queueCollection的副本。这应该减少队列被某个其他线程'锁定'并因此导致所述错误的机会。

或者,您可以尝试在访问queueCollection时使用同步。例如:

lock (wantMyQueue) 
{ 
    // Access queueCollection in here 
} 

其中wantMyQueue是一个简单的object全局变量。

+0

谢谢,虽然这些建议都没有奏效。 – mike9182 2011-03-11 02:47:54

+1

反正'queueCollection'是什么数据类型? – 2011-03-11 03:02:45

+0

+1 - queueCollection是什么类型?它在哪里宣布。你是否创建任何线程或背景工作者? – 2011-03-11 05:49:23

1

“PrintQueue”类型的行为类似于“DependencyObject”。它绑定到当前线程的“Dispatcher”,类似于WPF中的UI元素。这就是你不能在与创建队列的线程不同的线程上使用它。您必须缓存“PrintQueueData”对象(而不是“PrintQueue”对象)或在每个方法调用上实例化“PrintQueue”。

实际的异常来自“System.Print.PrintQueue.VerifyAccess()”所调用的“System.Windows.Threading.Dispatcher.VerifyAccess()”。只要您访问打印队列的属性或方法,就会调用后者。

相关问题