非UI线程:“调用线程无法访问此对象,因为它归不同的线程所有”

3
我有以下代码:

var queue = printer.PrintQueue;
var canPrint = ! Dispatcher.CurrentDispatcher.Invoke(()
                            => queue.IsPaperJammed || queue.IsOutOfPaper || 
                               queue.IsInError || queue.HasPaperProblem);

它抛出以下错误:

调用线程无法访问此对象,因为不同的线程拥有它

我已经在UI线程上尝试过(使用上面显示的dispatcher),也尝试在当前线程上执行(没有使用dispatcher)。

有没有一种方法可以询问一个对象是哪个线程拥有它?


有一种方法可以确定是否需要使用Dispatcher.Invoke。这样回答您的问题可以吗? - BradleyDotNET
@LordTakkera - 我不确定它是否有效,因为我尝试过使用Dispatcher和不使用Dispatcher,但两次都失败了,出现了相同的错误。我猜测可能有其他拥有线程在运行。 - Vaccano
1
创建“printer”是什么意思?我认为你很难弄清楚哪个线程拥有一个对象,但也许我们可以找出哪个线程是。 - vcsjones
我相信你对调度程序的调用会启动一个线程。(因此,试图使用你的队列的线程与创建它的线程不同。) 我建议将队列的创建移动到调用线程内部,或者将错误条件的测试移动到调用之前。更大的示例可能会有所帮助。(这个小示例甚至没有表明为什么需要多线程。) - Wonderbird
我认为你问错了问题。真正的问题在于,为什么你要尝试从一个不同的 Dispatcher 创建的对象访问到另一个不同的 Dispatcher? - 123 456 789 0
3个回答

4

0

尽管代码看起来很疯狂,但以下代码仍然无法正常工作,并且仍会抛出异常。

dlg.PrintTicket.PageMediaSize = new PageMediaSize(302.36220472, int.MaxValue);
dlg.PrintTicket.PageOrientation = PageOrientation.Portrait;

但是这段代码有效

dlg.PrintTicket = new PrintTicket()
{
    PageMediaSize = new PageMediaSize(273, int.MaxValue),
    PageOrientation = PageOrientation.Portrait,
};

当然,两段代码都必须在Application.Current.Dispatcher.Invoke(() => {})中,但第一段仍会抛出异常,而第二段将解决该问题


0

有一种方法可以确定当前线程是否拥有控件:
使用control.Dispatcher.CheckAccess()检查当前线程是否拥有该控件。如果它没有拥有它,那么使用调度程序Invoke一个Action


System.Printing.PrintQueue 没有 Dispatcher 成员(至少我没有找到)。 - Vaccano

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接