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

后端 未结 6 807
一向
一向 2020-11-28 10:16

Whenever I refresh a label, I got this error: The calling thread cannot access this object because a different thread owns it. I tried to invoke b

相关标签:
6条回答
  • 2020-11-28 10:23
    private void imgPayment_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(() =>
                {
                    try
                    {
                        label1.Content = "df";
                    }
                    catch
                    {
                        lostfocs ld = new lostfocs(up);
                        object obj = new object();
                        ld.Invoke("sdaf");
                    }
                }));
            }
    
    0 讨论(0)
  • 2020-11-28 10:24

    Several suggestions to use BeginInvoke, but no mention of EndInvoke. Good Practice is that 'every BeginInvoke has a matching EndInvoke' and certainly there needs to be some safeguard against race conditions (Think: what happens with multiple BeginInvoke of code but none have finished processing yet?)

    It's easy to forget, and I've seen this error (and, yes, it is an error) in both MSDN examples and published books on WinForms

    0 讨论(0)
  • 2020-11-28 10:28

    use Dispatcher.Invoke

    Example

        void modi()
        {
            if(!Dispatcher.CheckAccess())
            {
                Dispatcher.Invoke(
                        ()=>label1.Content = "df",DispatcherPriority.Normal);
            }
            else
            {
                label1.Content = "df";
            }
        }
    
    0 讨论(0)
  • 2020-11-28 10:29

    I started one non-UI Thread and within this thread I stared one UI thread too. So my requirement is like running an UI thread within a non-UI thread. When handling this scenario I got the following exception. "Exception: The calling thread cannot access this object because a different thread owns it."

    In this case I used the Dispatcher.Invoke method of the UI element as follows and it worked well.

    if (m_contextWindow == null)
    {   
        System.Threading.Thread newWindowThread = new System.Threading.Thread(new ThreadStart( () =>
        {
            // Create and show the Window
            m_contextWindow = new ContextWindow();
            m_contextWindow.DataContext = this;                            
            m_contextWindow.Show();
            // Start the Dispatcher Processing
            System.Windows.Threading.Dispatcher.Run();
        }));
    
        // Set the apartment state
        newWindowThread.SetApartmentState(ApartmentState.STA);
        // Make the thread a background thread
        newWindowThread.IsBackground = true;
        // Start the thread
        newWindowThread.Start();
    }
    else
    {                     
        this.m_contextWindow.Dispatcher.Invoke(new ThreadStart(() => 
        {
            m_contextWindow.DataContext = this;
            if (m_contextWindow.Visibility == System.Windows.Visibility.Collapsed
             || m_contextWindow.Visibility == System.Windows.Visibility.Hidden)
                m_contextWindow.Visibility = System.Windows.Visibility.Visible;
        }));                            
    }
    
    0 讨论(0)
  • 2020-11-28 10:31

    Use Dispatcher.Invoke Method.

    Executes the specified delegate synchronously on the thread the Dispatcher is associated with.

    Also

    In WPF, only the thread that created a DispatcherObject may access that object. For example, a background thread that is spun off from the main UI thread cannot update the contents of a Button that was created on the UI thread. In order for the background thread to access the Content property of the Button, the background thread must delegate the work to the Dispatcher associated with the UI thread. This is accomplished by using either Invoke or BeginInvoke. Invoke is synchronous and BeginInvoke is asynchronous. The operation is added to the event queue of the Dispatcher at the specified DispatcherPriority.

    You are getting the error because your label is created on UI thread and you are trying to modify its content via another thread. This is where you would require Dispatcher.Invoke.

    Check out this article WPF Threads Build More Responsive Apps With The Dispatcher

    0 讨论(0)
  • 2020-11-28 10:39

    You can use Dispatcher for this. Your code becomes...

    private void imgPayment_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        Dispatcher.BeginInvoke(DispatcherPriority.Input, new ThreadStart(() =>
        {
            try
            {
                label1.Content = "df";
            }
            catch
            {
                lostfocs ld = new lostfocs(up);
              //  ld.Invoke("df");
                object obj=new object();
                ld.Invoke("sdaf");
            }
        }
    ));
    
    0 讨论(0)
提交回复
热议问题