NoesisException: Calling thread (7516) doesn't have access to this object (5556)
I've come across an annoying error. Apparently I'm calling some code from another thread.
Setup
I've got a GameManager (Monobehaviour) class which holds a bunch of commands (can be added from anywhere in the code) which need to be executed on various objects. One of those commands is the switching of a view. When the Update() method is called on the GameManager, all the commands which were stored are getting called on the listeners.
One of those listeners is my viewmodel for my main view. It listens for a change of view command and executes the code to load a xaml from code.
Classes
MainViewModel
GameManager (relevant part)
Stacktrace
Setup
I've got a GameManager (Monobehaviour) class which holds a bunch of commands (can be added from anywhere in the code) which need to be executed on various objects. One of those commands is the switching of a view. When the Update() method is called on the GameManager, all the commands which were stored are getting called on the listeners.
One of those listeners is my viewmodel for my main view. It listens for a change of view command and executes the code to load a xaml from code.
Classes
MainViewModel
Code: Select all
public class MainVM : BaseVM, IChangeUIViewCommand
{
#region Private Fields
private Panel _contentContainer;
#endregion Private Fields
#region Public Constructors
public MainVM(Panel contentContainer) : base()
{
_contentContainer = contentContainer;
GameManager.Subscribe(this, Enums.CommandType.ChangeUIView);
}
#endregion Public Constructors
#region Public Methods
public void ChangeUI(Enums.UILevel uiLevel)
{
object usercontrol = null;
_contentContainer.Children.Clear();
var xamlLocation = "";
switch (uiLevel)
{
case Enums.UILevel.None:
break;
case Enums.UILevel.Login:
xamlLocation = "Assets/UI/Views/Login.xaml";
break;
case Enums.UILevel.CharacterSelection:
xamlLocation = "Assets/UI/Views/CharacterSelection.xaml";
break;
case Enums.UILevel.CharacterCreation:
xamlLocation = "Assets/UI/Views/CharacterCreation.xaml";
break;
case Enums.UILevel.Ingame:
xamlLocation = "Assets/UI/Views/Ingame.xaml";
break;
case Enums.UILevel.Loading:
xamlLocation = "Assets/UI/Views/Loading.xaml";
break;
}
usercontrol = Noesis.GUI.LoadXaml(xamlLocation);
if (usercontrol != null)
_contentContainer.Children.Add(usercontrol);
}
#endregion Public Methods
}
Code: Select all
private void Update()
{
while (_commandQueue.Count > 0)
{
var command = _commandQueue.Dequeue();
if (command.IsNetworkCommand)
ExecuteNetworkCommand(command);
else
ExecuteLocalCommand(command);
command.Recycle();
}
}
private void ExecuteLocalCommand(Command command)
{
var commandListenersByType = _commandListeners[command.CommandType];
for (int j = 0; j < commandListenersByType.Count; j++)
command.Execute(commandListenersByType[j]);
}
Code: Select all
PulatiaUI.CharacterSelection:.ctor() (at Assets/UI/Views/CharacterSelection.xaml.cs:36)
System.Runtime.CompilerServices.ExecutionScope:lambda_method(ExecutionScope)
Noesis.Extend:CreateInstance(IntPtr, IntPtr) (at Assets/NoesisGUI/Plugins/API/Core/NoesisExtend.cs:3887)
Noesis.GUI:Noesis_LoadXaml(String)
Noesis.GUI:Noesis_LoadXaml_(String) (at Assets/NoesisGUI/Plugins/API/Core/NoesisGUI.cs:262)
Noesis.GUI:LoadXaml(String) (at Assets/NoesisGUI/Plugins/API/Core/NoesisGUI.cs:120)
Assets.UI.ViewModels.MainVM:ChangeUI(UILevel) (at Assets/UI/ViewModels/MainVM.cs:90)
Pulatia.Network.Common.Commands.ChangeUIViewCommand:Execute(ICommandListener)
GameManager:ExecuteLocalCommand(Command) (at Assets/Scripts/Managers/GameManager.cs:141)
GameManager:Update() (at Assets/Scripts/Managers/GameManager.cs:116)
-
sfernandez
Site Admin
- Posts: 2984
- Joined:
Re: NoesisException: Calling thread (7516) doesn't have access to this object (5556)
Hi,
In NoesisGUI UI elements can only be accessed from the thread where they were created, and they should live in the same thread as the View where they are connected to.
Could you please create a ticket in our bugtracker and attach your project files. This way we can help you figure out which elements are being accessed from the incorrect thread.
Thanks.
In NoesisGUI UI elements can only be accessed from the thread where they were created, and they should live in the same thread as the View where they are connected to.
Could you please create a ticket in our bugtracker and attach your project files. This way we can help you figure out which elements are being accessed from the incorrect thread.
Thanks.
Re: NoesisException: Calling thread (7516) doesn't have access to this object (5556)
Thank you for getting back at me. Here is some more information, because it might just be some misunderstanding from my part about the threads being used here.
In the above image, the [Managers] gameobject is using the same thread as the "Noesis View" with the Main.xaml file right? The MainVM class I mentioned in my original post is assigned to the datacontext for the Main.xaml. Am I correcty in saying that the MainVM class is running on the same thread as the [Managers] gameobject?
When using the Noesis.GUI.LoadXaml(xamlLocation) method, the loaded xaml is also on the same thread as the Main.xaml (meaning on the same thread as the Managers gameobject aswell) right? Or am I wrong here?
PS: All my loaded xamls are being added to the Main.xaml as children of a grid in that Main.xaml.
In the above image, the [Managers] gameobject is using the same thread as the "Noesis View" with the Main.xaml file right? The MainVM class I mentioned in my original post is assigned to the datacontext for the Main.xaml. Am I correcty in saying that the MainVM class is running on the same thread as the [Managers] gameobject?
When using the Noesis.GUI.LoadXaml(xamlLocation) method, the loaded xaml is also on the same thread as the Main.xaml (meaning on the same thread as the Managers gameobject aswell) right? Or am I wrong here?
PS: All my loaded xamls are being added to the Main.xaml as children of a grid in that Main.xaml.
Re: NoesisException: Calling thread (7516) doesn't have access to this object (5556)
As you are not the first user reporting this problem, we think there may be a bug in Noesis regarding this. You are not using threads in your application right? Would it be possible to have a copy of your project to analyze and reproduce the issue? (in the tracker)
Thanks!
Thanks!
-
sfernandez
Site Admin
- Posts: 2984
- Joined:
Re: NoesisException: Calling thread (7516) doesn't have access to this object (5556)
Do you have any script that creates any Noesis UI element or resource as a static field?
Something like this:
Because that will lead to Unity initializing that field during UnityPreload thread, which executes Noesis initialization in the incorrect thread.
Something like this:
Code: Select all
public class TestBehavior: MonoBehavior
{
private static Noesis.TextBlock textBlock = new TextBlock();
...
}
-
sfernandez
Site Admin
- Posts: 2984
- Joined:
Re: NoesisException: Calling thread (7516) doesn't have access to this object (5556)
I found the following in Unity forums:
Monobehaviours can't have Constructors.
The reason for this is that in Editor, to fill up the Inspector they get created/destroyed on a separate editor thread. This causes Unity threading issues primarily, but will also cause more strange issues because you can't reference singletons or some static variables, as the object is being created completely out of the game flow.
Who is online
Users browsing this forum: No registered users and 102 guests