线程错误-分派器? [英] Threading Error - Dispatcher?

查看:63
本文介绍了线程错误-分派器?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的问题的简化版本.
我复制了确切的类结构,仅包含必要的代码.

Here is a dummed-down version of my problem.
I replicated the exact class structure and only included the necessary code.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Printing;
using System.Threading;
using System.ComponentModel;

namespace ThreadAndSpool
{
    class MyMainProcessClass
    {
        MyBackgrounWorkerClass bw = new MyBackgrounWorkerClass();
        public MyMainProcessClass()
        {
            bw.Start();
        }
    }

    class MyBackgrounWorkerClass
    {
        private BackgroundWorker _bw = new BackgroundWorker();
        private PrintHost _ph;

        public MyBackgrounWorkerClass()
        {
            _ph = new PrintHost();
            _bw.DoWork += new DoWorkEventHandler(bw_DoWork);
        }

        private void bw_DoWork(object sender, DoWorkEventArgs e)
        {
            _ph.CheckHost();
        }

        public void Start()
        {
            _bw.RunWorkerAsync();
        }
    }

    class PrintHost
    {
        public PrintServer _hostingServer;
        public PrintHost()
        {
            _hostingServer = new PrintServer(@"\\" + Environment.MachineName, PrintSystemDesiredAccess.AdministrateServer);
        }

        public void CheckHost()
        {
            _hostingServer.Refresh();
        }
    }
}



该行包含:



The line containing:

_hostingServer.Refresh();


导致以下运行时错误:


Causes the following runtime error:

"The calling thread cannot access this object because a different thread owns it."



我猜想调用过程是"MyMainProcesssClass",我必须实现一个Dispatcher,但是到目前为止,我还无法解决这个错误.

根据要求,我在VS2008 c#项目中有此简化的代码.



I''m guessing that calling process is "MyMainProcesssClass" and that I have to implement a Dispatcher, but so far I''ve not been able to get around this error.

At request I have this dummed-down code in a VS2008 c# project.

推荐答案

回答以下问题之一:InvokeRequred可以在以下任何一个对象上调用当前正在运行的UI中涉及的控件.通常,在调用中使用的控件上在"if"下调用它.

现在,大多数情况下实际上并不需要InvokeRequred.如果从非UI线程调用它,则总是会返回true.仅在一种情况下需要此方法:将其放在有时从UI线程调用,有时在其他线程中调用的某种方法中.人们错误地认为此功能过于重要.

我在过去的解决方案中详细解释了调用机制.

您无法从非UI线程调用与UI相关的任何操作.相反,您需要使用System.Windows.Threading.DispatcherInvokeBeginInvoke方法(对于Forms或WPF)或System.Windows.Forms.Control(仅对于Forms).

在我过去的答案中,您将找到有关其工作原理的详细说明和代码示例:
Control.Invoke()与Control.BeginInvoke() [ ^ ],
Treeview Scanner和MD5的问题 [如何获取keydown事件在vb.net中的不同线程上操作 [启用禁用+多线程后控件事件不会触发 [ ^ ].

—SA
Answering one of the follow-up questions: InvokeRequred can be called on any of the controls involved in the currently running UI. Usually it is called on the control which is used in the invocation following under "if".

Now, InvokeRequred is not really needed in most cases. If you call it from non-UI thread is will always return true. This method is needed only in one case: you put it in some method which sometimes is called from UI thread, sometimes in some other thread. People mistakenly attribute too much importance to this function.

I explained the mechanism of invocation in detail in my past solutions.

You cannot call anything related to UI from non-UI thread. Instead, you need to use the method Invoke or BeginInvoke of System.Windows.Threading.Dispatcher (for both Forms or WPF) or System.Windows.Forms.Control (Forms only).

You will find detailed explanation of how it works and code samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke()[^],
Problem with Treeview Scanner And MD5[^].

See also more references on threading:
How to get a keydown event to operate on a different thread in vb.net[^],
Control events not firing after enable disable + multithreading[^].

—SA


BackgroundWorker在与创建它的线程(和您的PrintHost实例)不同的线程中执行您的任务.您需要使用InvokeRequiredInvoke进行跨线程方法调用.
BackgroundWorker executes your tasks in a different thread than the one that creates it (and your PrintHost instance). You''ll need to use InvokeRequired and Invoke to make cross-thread method calls.


这篇关于线程错误-分派器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆