简体   繁体   English

调用线程无法访问该对象,因为其他线程拥有它

[英]The calling thread cannot access this object because a different thread owns it

Ok, my current code is work in progress and probably I will try to do the same thing with the Async CTP. 好的,我当前的代码正在开发中,可能我将尝试使用异步CTP做同样的事情。 But I will still like to understand whats happening. 但是我仍然想了解发生了什么。

I have a function like below 我有一个像下面的功能

// In MainWindow.xaml.cs
Task.Factory.StartNew(() => helper.Send());

// In class HttpHelper
public void Send()
{
    // ...

    try
    {
        Status = Statuses.Uploading;
        // write to request stream

        Status = Statuses.Downloading;
        // write to response stream

        Status = Statuses.Idle; // the exception is thrown here
        // ...
    }
    catch (Exception e)
    {
        // ...
    }
}

Full Code for HttpHelper @pastebin . HttpHelper @pastebin的完整代码。 Send() on line 76 第76行的Send()

I wonder why I get the exception? 我想知道为什么我会得到例外? Maybe I did something wrong with the threading, but why is the exception raised only after I successfully set the Status property 2 times? 也许我在线程处理方面做错了什么,但是为什么仅在成功设置Status属性2次后才引发异常?

UPDATE: The Cause ... 更新:原因...

I had an event handler, listening to the StatusChanged event, in 1 if clause, I forgot to use the UI thread to update the UI 我有一个事件处理程序,在1 if子句中监听StatusChanged事件,我忘记了使用UI线程来更新UI

helper.StatusChanged += (s, evt) =>
{
    _dispatcher.Invoke(new Action(() => txtStatus.Text = helper.Status.ToString())); // I used _dispatcher here correctly

    if (helper.Status == HttpHelper.Statuses.Idle || helper.Status == HttpHelper.Statuses.Error)
       progBar.IsIndeterminate = false; // but not here
};

Update : I missed the (in my defense, small) comment in your code that gave away that you're using WPF/Silverlight and not Windows Forms. 更新 :我错过了代码中的(为了辩护,在小的情况下)注释,但该注释表明您使用的是WPF / Silverlight,而不是Windows窗体。

Still, looks like you were able to take the basic gist of what I said and apply it to your own scenario properly (using Dispatcher.Invoke rather than Control.Invoke )—well done ;) 不过,看起来您已经能够理解我所说的基本内容并将其正确地应用于您自己的场景(使用Dispatcher.Invoke而不是Control.Invoke )—做得很好;)


I'm guessing an event handler attached to your StatusChanged event updates a StatusLabel control on your UI? 我猜测附加到StatusChanged事件的事件处理程序会更新UI上的StatusLabel控件吗? If that's the case, then you need to Invoke that call from the UI thread; 如果是这种情况,那么您需要从UI线程Invoke该调用; eg: 例如:

void HttpHelper_StatusChanged(object sender, EventArgs e)
{
    var httpHelper = (HttpHelper)sender;
    UpdateStatus(httpHelper.Status);
}

void UpdateStatus(HttpHelper.Statuses status)
{
    if (InvokeRequired)
    {
        Invoke(new Action<HttpHelper.Statuses>(UpdateStatus), status);
    }
    else
    {
        // Your code probably doesn't look like this;
        // it's just an example.
        statusLabel.Text = status.ToString();
    }
}

The reason you might see two successes followed by a failure is a bit beyond me; 您可能会看到两次成功之后又一次失败的原因超出了我一些; but I know that the StatusLabel control in particular can be a bit evasive when it comes to threading issues. 但是我知道,特别是在涉及线程问题时, StatusLabel控件可能会有点回避。 I have seen code where it is updated directly from background threads (typically due to developer obliviousness) without any exception; 我已经看到了从后台线程直接进行更新的代码(通常是由于开发人员的遗忘),没有任何异常; it looks to me like you just got lucky twice and unlucky once. 在我看来,您幸运两次,而不幸一次。

Does Status touch the UI? Status是否触及用户界面? Because it seems like it. 因为看起来像。

I can only guess but I imagine Status changes something on UI which needs to be done through Dispatcher.Invoke() . 我只能猜测,但是我想Status会在UI上发生一些变化,这需要通过Dispatcher.Invoke()

if Status is a global variable you will get this exception becuase multiple threads are accessing and updating it at the same time. 如果Status是全局变量,则由于多个线程正在同时访问和更新它,因此将获得此异常。 i suggest to use a lock around it 我建议在它周围使用锁

暂无
暂无

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

相关问题 调用线程无法访问该对象,因为其他线程拥有它错误 - 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 调用线程无法访问此对象,因为另一个线程拥有它“异常” - The calling thread cannot access this object because a different thread owns it “exception” WPF:调用线程无法访问此对象,因为其他线程拥有它 - WPF: The calling thread cannot access this object because a different thread owns it 调用线程无法访问此 object,因为不同的线程拥有它 - The calling thread cannot access this object because a different thread owns it 调用线程无法访问此 object,因为不同的线程拥有它 - 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 调用线程无法访问该对象,因为其他线程拥有它 - 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