简体   繁体   English

从不同的线程访问对象

[英]access object from a different thread

I have a Server class which it basically waits for connections from a client. 我有一个Server类,它基本上等待来自客户端的连接。 Inside that class I create an NetworkStream object in order to be able to receive bytes from a client. 在该类中,我创建了一个NetworkStream对象,以便能够从客户端接收字节。 Because the NetworkStream.Read() method is not asynchronous (meaning that it will wait until it reads bytes from a client in order to proceed executing code similar to the messagebox method), I have to read for bytes in a separate thread so that the user using the program can still interact with the program if the program happens to be waiting to read for data. 因为NetworkStream.Read()方法不是异步的(意味着它会等到它从客户端读取字节以继续执行类似于messagebox方法的代码),所以我必须在一个单独的线程中读取字节,以便如果程序恰好等待读取数据,则使用该程序的用户仍然可以与程序交互。

anyways a lot of objects are owned by that thread. 无论如何,该线程拥有许多对象。 One example is that I have a List called log in that class. 一个例子是我在该类中有一个名为log的List。 I use that list to know the status of the server. 我使用该列表来了解服务器的状态。 Maybe it is listening for a connection or perhaps it's status is "connected" or "disconnected". 也许它正在监听连接,或者它的状态是“连接”或“断开连接”。

So if I do something like: 所以如果我这样做:

Server myServer = new Server("192.168.0.120","1300"...\\ I pass the appropite parameters in order to instantiate it

//...
.. then I am able to latter look at the log as
string foo = myServer.Log[0] for example.

because I want to know when the log is updated, on the server class I have created an event as: 因为我想知道日志何时更新,在服务器类上我创建了一个事件:

    public delegate void onUpdateHandler(string newStatus);
    public event onUpdateHandler onUpdate = delegate { };

I then fire events on the Server class as: 然后,我在Server类上触发事件:

 onUpdate("waitingForConnection");

and I receive those events with the method: 我用这个方法收到这些事件:

在此输入图像描述

but if I try to do something with newStatus I get the error stating: 但如果我尝试用newStatus做一些事情,我会收到错误说明:

System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it.

so how can I pass an object with an event? 那我怎么能用事件传递一个对象呢?


Edit 编辑

so I also notice that if I do: 所以我也注意到如果我这样做:

在此输入图像描述

I also get an error! 我也收到错误!

but when I do the same thing calling that from a button as: 但当我做同样的事情时,从按钮调用:

   // SERVER IS RUNNING BEFORE CALLING THIS METHOD
    private void button3_Click(object sender, RoutedEventArgs e)
    {

        listView1.Items.Add("my own string");

    }

I do NOT get an error! 我没有收到错误!

why is it that I get an error with the event and I do not get an error when calling it with a regular button. 为什么我在事件中遇到错误,并且在使用常规按钮调用时没有出错。

The problem is that the thread tries to access the ListView which is a DependencyObject which has thread affinity, use the Dispatcher to execute methods like this on the UI-thread, eg: 问题是线程试图访问ListView,它是一个具有线程亲和性的DependencyObject ,使用Dispatcher在UI线程上执行这样的方法,例如:

Application.Current.Dispatcher.Invoke((Action)(() =>
{
    listView1.Items.Add(newStatus);
}));

Also see the threading model reference for additional info. 另请参阅线程模型参考以获取其他信息。

The problem is not that you try to do something with the value that you sent to the method, the problem is what you are trying to do with it. 问题不在于您尝试使用发送给方法的值执行某些操作,问题在于您尝试使用它。

The event handler is still running in your background thread, and from there you can't use any UI controls as they belong to the main thread. 事件处理程序仍然在后台线程中运行,从那里你不能使用任何UI控件,因为它们属于主线程。

The usual way of handling that is to use the CheckAccess method to check if you need to switch treads, and the Invoke method to hand off the work to the main thread: 通常的处理方法是使用CheckAccess方法检查是否需要切换踏板,使用Invoke方法将工作交给主线程:

void server_onUpdate(string newStatus) {
  if (!listView1.Dispatcher.CheckAccess()) {
    listView1.Dispatcher.Invoke(server_onUpdate, newStatus)
  } else {
    listView1.Items.Add(newStatus);
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 访问不同线程中的对象 - Access object in a different thread WPF线程和GUI如何从不同的线程访问对象? - WPF thread and GUI how to access object from different thread? 从控制台应用程序C#访问不同线程中的对象 - Get access to object in the different thread from console app c# 如何从其他线程访问对象而不会发生冲突? - How to access an object from a different thread without conflict? 从WPF中的其他线程更新UI控件时,出现“调用线程无法访问该对象,因为其他线程拥有该对象”错误 - “The calling thread cannot access this object because a different thread owns it” error when updating UI control from different thread in WPF 调用线程无法访问此对象,因为其他线程拥有 - The calling thread cannot access this object because a different thread owns 调用线程无法访问该对象,因为其他线程拥有它 - The calling thread cannot access this object because a different thread owns it 调用线程无法访问该对象,因为其他线程拥有它 - The calling thread cannot access this object because a different thread owns it 调用线程无法访问此对象,因为另一个线程拥有它 - The calling thread cannot access this object because a different thread owns it 错误:调用线程无法访问此对象,因为其他线程拥有它 - Error:The calling thread cannot access this object because a different thread owns it
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM