DevFear
Topic Author
Posts: 53
Joined: 29 Jun 2022, 12:36

ObservableCollection AddRange vs Async Method

25 Oct 2023, 11:32

Hi. ObservableCollection does not support adding a list at a time, so I implemented my own class that contains methods for working with ranges:
public void AddRange(IEnumerable<T> collection, bool sendResetAction = false)
{
	if (collection == null)
		throw new ArgumentNullException(nameof(collection) + " is null!");

		if (!collection.Any())
			return;

		CheckReentrancy();

		var tempList = new List<T>();

		foreach (var item in collection)
		{
			tempList.Add(item);
			Items.Add(item);
		}

		if (sendResetAction)
			InvokeCollectionModificationEvent(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
		else
			InvokeCollectionModificationEvent(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, tempList));
	}
The collection works, but the problem is in the event type NotifyCollectionChangedAction. If you call the Add event, the UI updates the collection perfectly. However, if you update the collection in the aync method, Unity will crash:
	
public async void ReloadYards()
	{
		var yards = new List<YardHeader>();

		await Task.Delay(100);

		for (int i = 0; i < 15; i++)
		{
			yards.Add(new YardHeader(Guid.Empty, i.ToString(), null));
		}

		_yardHeaders.AddRange(yards);		
}
At the same time, if you call the reset event, then everything works fine.
 
User avatar
sfernandez
Site Admin
Posts: 3008
Joined: 22 Dec 2011, 19:20

Re: ObservableCollection AddRange vs Async Method

31 Oct 2023, 12:51

Hi,

Modifying a bound collection in a different thread is not supported and can lead to crashes.
But we have plans to support that scenario directly in the binding engine: #2256

In the meantime you will need to enqueue the change notification to the main thread where UI tree is created and updated.

Could you please try that?
 
User avatar
sfernandez
Site Admin
Posts: 3008
Joined: 22 Dec 2011, 19:20

Re: ObservableCollection AddRange vs Async Method

02 Nov 2023, 10:10

However, if you update the collection in the aync method, Unity will crash
Regarding this, could you please create a ticket in our bugtracker and attach a crash dump, because we don't want Unity to crash.
 
User avatar
nadjibus
Posts: 33
Joined: 24 Feb 2022, 04:09

Re: ObservableCollection AddRange vs Async Method

04 Nov 2023, 17:54

Doesn't the collection modification happens in the main thread in the above code example since there's no ConfigureAwait(false) ?
 
DevFear
Topic Author
Posts: 53
Joined: 29 Jun 2022, 12:36

Re: ObservableCollection AddRange vs Async Method

10 Nov 2023, 12:28

Source: "Unity overwrites the default SynchronizationContext with a custom UnitySynchronizationContext and runs all the tasks on the main thread in both Edit and Play modes. To utilize async tasks, you must manually create and handle your own threads with a TaskFactory, as well as use the default SynchronizationContext instead of the Unity version. To listen for enter and exit play mode events to stop the tasks manually, use EditorApplication.playModeStateChanged. However, if you take this approach, most of the Unity scripting APIs are not available to use because you are not using the UnitySynchronizationContext."

The above implementation does not use multithreading. Technically, it's corutine. It might be worth checking the implementation with IEnumerator as well.
 
User avatar
sfernandez
Site Admin
Posts: 3008
Joined: 22 Dec 2011, 19:20

Re: ObservableCollection AddRange vs Async Method

13 Nov 2023, 12:39

Would it be possible to get the crash dump when using the async method?

Who is online

Users browsing this forum: Bing [Bot] and 8 guests