Huskinu
Posts: 12
Joined: 15 Mar 2021, 05:40

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

14 Apr 2021, 08:35

Hi sfernandez,

Is that it is not yet supported in C++ SDK 3.0.11? I don't see the Invoke() in NoesisSDK/Include/NsGui/DispatcherObject.h
And also in UE, when I run this snippet under a custom handler named `OnInitialized()`, which is bound to FrameworkElement::Initialized event:
class CustomUIControl: public Noesis::UserControl
{
    bool ConnectEvent(Noesis::BaseComponent* source, const char* event, const char* handler) override
    {
        NS_CONNECT_EVENT(Noesis::Button, Initialized, OnInitialized);
         return true;
    }
    
    virtual void OnInitialized(Noesis::BaseComponent* InSender, const Noesis::EventArgs& InEventArgs) override
    {
        Noesis::Button* button = Noesis::DynamicCast<Noesis::Button*>(InSender);
        verify(button);
        button->VerifyAccess();
        button->SetContent("Ok"); -> It crashes here!
    }
};
, it just crashed and raises the error:
LogNoesis: Warning: The calling thread (7368) cannot access this Boxed<String> because a different thread (0) owns it
 
User avatar
sfernandez
Site Admin
Posts: 2984
Joined: 22 Dec 2011, 19:20

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

14 Apr 2021, 15:07

Is that it is not yet supported in C++ SDK 3.0.11? I don't see the Invoke() in NoesisSDK/Include/NsGui/DispatcherObject.h
Dispatcher won't be implemented in the C++ SDK, our core library doesn't create or manages threads, that is something that should be done by the user.

Regarding the crash, I'm not able to compile your code if I include the override specifier for the OnInitialized function. There is no base class for UserControl with a virtual function named OnInitialized. And if I remove the override specifier everything seems to work as expected.

Would it be possible to get a crash dump (minidump) because it is strange that the log message refers to the boxed string?
 
Huskinu
Posts: 12
Joined: 15 Mar 2021, 05:40

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

17 Apr 2021, 10:13

Hi sfernandez,

Thanks for your confirmation! Sorry, I actually copied the source here from my customized one and forgot to remove override.
Yeah I'm trying to figure out why it works fine with this UserControl tutorial example as you also tried, but does not with my custom source though I have no worker threads handle UI interactions.

Actually, also what I tried are:
* Replacing TextBlock with a Button here:
<Button Grid.RowSpan="2" VerticalAlignment="Center" Margin="5,3,4,3" ClickMode="Press"
        Content="{Binding Content, ElementName=NumericUpDownControl}"
        Initialized="OnInitialized"/>
* Then inserting Content="abc" into this line, which also causes a crash in the UE Editor with the same warning, specifically when I reimport the xaml -> uasset.

Would you mind helping give some diagnosis?

Thanks.
 
User avatar
sfernandez
Site Admin
Posts: 2984
Joined: 22 Dec 2011, 19:20

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

19 Apr 2021, 11:12

I see you are binding Content property of the NumericUpDownControl to the Content of the Button, creating a loop in the logical tree, I guess you wanted to bind Value property instead. Anyway, we should detect those situations and don't crash, could you please report it?
 
Huskinu
Posts: 12
Joined: 15 Mar 2021, 05:40

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

19 Apr 2021, 12:47

Hi sfernandez,
Oh so that created a binding loop? I am just a bit confused, so just to get some more details for the report, since we don't specify Mode=TwoWay there, and if Button's Content is bound to NumericUpDownControl's Content, is that still one-way binding?

And this pure xaml is apart from my earlier question above, where I used cpp to set Button' Content directly. I mean I tried both ways and they both raised the same warning (Just the cpp one seems to come from some fault in my own custom source).
Thank you.
 
User avatar
sfernandez
Site Admin
Posts: 2984
Joined: 22 Dec 2011, 19:20

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

19 Apr 2021, 13:34

The problem is in the UI tree, not the binding type. With that binding you are creating this loop:
<UserControl> (NumericUpDownControl)
  <Grid> (this is the NumericUpDownControl Content)
    <Button>
     (You are setting here the Grid (Button's parent) as Content)
    </Button>
  </Grid>
</UserControl>
What you probably wanted to do is binding the Value property:
<Button Content="{Binding Value, ElementName=NumericUpDownControl}" .../>
 
Huskinu
Posts: 12
Joined: 15 Mar 2021, 05:40

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

21 Apr 2021, 08:37

Oh, sorry I'm still new to xaml and still trying to know more. So by this line
<Button Content="{Binding Content, ElementName=NumericUpDownControl}" .../>
I would understand as the Button's Content take its value from NumericUpDownControl's Content, which I suppose is initialized in the parent MainWindow.xaml.

If it could not, I would feel it as a bit of constraint since I actually want to create a CustomButton (of UserControl type) that wraps <Button> inside itself, then in the user xaml like MainWindow.xaml, I could create multiple CustomButton and specify their Content (not Value) directly in xaml. Otherwise, I have to do in in cpp, which might be not very convenient since this is purely UI configuration I guess.

Besides, I actually also tried binding with Name property like
<Button Content="{Binding Name, ElementName=NumericUpDownControl}" .../>
and NumericUpDownControl's Name property could well be configured directly in MainWindow.xaml as in here, and it works.
So is there some specific difference between the initializing of Name and Content properties?
Thanks.
 
User avatar
sfernandez
Site Admin
Posts: 2984
Joined: 22 Dec 2011, 19:20

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

21 Apr 2021, 11:47

I would understand as the Button's Content take its value from NumericUpDownControl's Content, which I suppose is initialized in the parent MainWindow.xaml.
No, the Content of the NumericUpDownControl is defined by the NumericUpDownControl.xaml. Setting UserControl's content in the parent MainWindow.xaml has no sense (in most cases) because you will be overriding everything defined in the xaml.

If you need to specify some content for your own user control you can define a new property, like we did in the NumericUpDownControl with the Value property.

MainWindow.xaml
<Grid x:Name="MainWindowRoot">
  ...
  <local:MyUserControl>
    <local:MyUserControl.MyContent>
      <Rectangle Width="100" Height="100" Fill="Red"/>
    </local:MyUserControl.MyContent>
  </local:MyUserControl>
</Grid>
MyUserControl.xaml
<UserControl x:Class="Tests.MyUserControl"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:local="clr-namespace:Tests"
  x:Name="MyUserControlName">
  <ContentPresenter Content="{Binding MyContent, ElementName=MyUserControlName}"/>
</UserControl>
So is there some specific difference between the initializing of Name and Content properties?
The difference is, as I explained before, that Content property is set with the contents of the NumericUpDown.xaml, so creating inside that xaml a binding to that content will create a circular reference in the UI logical tree:
UserControl
 Grid (= UserControl.Content)
  Button
    Grid (= Button.Content = UserControl.Content)
      Button
        Grid (= Button.Content = UserControl.Content)
          ... (and forever)
 
Huskinu
Posts: 12
Joined: 15 Mar 2021, 05:40

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

21 Apr 2021, 11:57

Oh I see now, so I figure Content is not simply an atomic-like property, but it is well coupled with the whole contents of NumericUpDownControl, which essentially includes all the child controls' Content, and thus it could not be bound to the parent's one.
Yeah, I was actually trying to do a pure XAML setup without having to write some binding cpp source like with Value property, since in this case it is just the Button's text content.
Thanks a lot for your detailed explanation!

Who is online

Users browsing this forum: No registered users and 26 guests