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

System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it.
   at System.Windows.Threading.Dispatcher.VerifyAccess()
   at System.Windows.FrameworkContentElement.ChangeLogicalParent(DependencyObject newParent)
   at System.Windows.FrameworkContentElement.AddLogicalChild(Object child)
   at System.Windows.LogicalTreeHelper.AddLogicalChild(DependencyObject parent, Object child)
   at System.Windows.Documents.TextContainer.InsertElementInternal(TextPointer startPosition, TextPointer endPosition, TextElement element)
   at System.Windows.Documents.TextElement.RepositionWithContent(TextPointer textPosition)
   at System.Windows.Documents.TextElementCollection`1.Add(TextElementType item)
   at WpfApp111.MainWindow.<Timer_Elapsed>b__10_0() in D:\C\WpfApp111\MainWindow.xaml.cs:line 45
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.DispatcherOperation.InvokeImpl()
   at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
   at MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(Object obj)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Windows.Threading.DispatcherOperation.Invoke()
   at System.Windows.Threading.Dispatcher.ProcessQueue()
   at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
   at System.Windows.Application.RunDispatcher(Object ignore)
   at System.Windows.Application.RunInternal(Window window)
   at System.Windows.Application.Run(Window window)
   at System.Windows.Application.Run()
   at WpfApp111.App.Main()

Copy from https://www.iditect.com/guide/csharp/error-the-calling-thread-cannot-access-this-object-because-a-different-thread-owns-it.html

The "The calling thread cannot access this object because a different thread owns it" error occurs in C# when you try to access or modify a UI element from a thread other than the one that created it. In WPF and WinForms applications, UI elements can only be accessed or modified by the thread that created them, which is usually the main (UI) thread.

 

  • For WPF applications, use the Dispatcher:
Application.Current.Dispatcher.Invoke(() =>
{
    // Access or modify UI elements here
});


 private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
 {
     str = $"{++num}_{DateTime.Now.ToString("yyyyMMddHHmmssffff")}_{Guid.NewGuid().ToString()}\n";
     
     Application.Current.Dispatcher.BeginInvoke(new Action(() =>
     {
         rtbRun = new Run(str);
         //testParagraph.Inlines.Clear();
         testParagraph.Inlines.Add(rtbRun);
     }));
 }

 

 

//whole code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApp111
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        static UInt64 num = 0;
        private string str { get; set; } = string.Empty;
        private Run rtbRun { get; set; } 

        public MainWindow()
        {
            InitializeComponent();
            System.Timers.Timer timer = new System.Timers.Timer();
            timer.Elapsed += Timer_Elapsed;
            timer.Interval = 1000;
            timer.Start();
        }

        private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            str = $"{++num}_{DateTime.Now.ToString("yyyyMMddHHmmssffff")}_{Guid.NewGuid().ToString()}\n";
            
            Application.Current.Dispatcher.BeginInvoke(new Action(() =>
            {
                rtbRun = new Run(str);
                //testParagraph.Inlines.Clear();
                testParagraph.Inlines.Add(rtbRun);
            }));
        } 
    }
}

 

posted @ 2024-05-24 11:43  FredGrit  阅读(28)  评论(0编辑  收藏  举报