-
Notifications
You must be signed in to change notification settings - Fork 49
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2262 from unoplatform/mergify/bp/release/stable/4…
….1/pr-2250 fix(mvux): Properties update might be deferred too long if dispatcher is under heavy stress (backport #2250)
- Loading branch information
Showing
6 changed files
with
140 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
70 changes: 70 additions & 0 deletions
70
src/Uno.Extensions.Reactive.Tests/Presentation/Bindings/Given_BindableViewModelBase.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using FluentAssertions; | ||
using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
using Uno.Extensions.Reactive.Testing; | ||
|
||
namespace Uno.Extensions.Reactive.Tests.Presentation.Bindings; | ||
|
||
[TestClass] | ||
public partial class Given_BindableViewModelBase : FeedUITests | ||
{ | ||
[TestMethod] | ||
public async Task When_UpdateSourceMultipleTimeWhileUIThreadFreeze_Then_LastWin() | ||
{ | ||
var sut = new BindableWhen_UpdateSourceMultipleTimeWhileUIThreadFreeze_Then_LastWin_Model(); | ||
|
||
var changes = 0; | ||
var uiFrozen = new ManualResetEvent(false); | ||
var bgCompleted = new ManualResetEvent(false); | ||
|
||
// First complete init, including changes raised on the UI thread | ||
await Dispatcher.ExecuteAsync(_ => sut.PropertyChanged += (snd, e) => changes++, CT); | ||
await WaitFor(() => sut.Value == 42 && changes is 1); | ||
|
||
// Freeze the UI thread | ||
Dispatcher.TryEnqueue(() => | ||
{ | ||
uiFrozen.Set(); | ||
bgCompleted.WaitOne(); | ||
}).Should().BeTrue(); | ||
uiFrozen.WaitOne(1000).Should().BeTrue(); | ||
|
||
// Update the source multiple times from bg thread | ||
await sut.Model.Value.SetAsync(43, CT); | ||
await sut.Model.Value.SetAsync(44, CT); | ||
await sut.Model.Value.SetAsync(45, CT); | ||
await sut.Model.Value.SetAsync(46, CT); | ||
|
||
// Release the UI thread so it can process the changes | ||
bgCompleted.Set(); | ||
await Dispatcher.ExecuteAsync(_ => { }, CT); // Wait for the UI thread to run something | ||
|
||
// Confirm the last change has been applied | ||
await WaitFor(() => sut.Value == 46); | ||
changes.Should().Be(2); // And only one property changed should have been raised for all changes | ||
} | ||
|
||
public partial class When_UpdateSourceMultipleTimeWhileUIThreadFreeze_Then_LastWin_Model | ||
{ | ||
public IState<int> Value => State<int>.Value(this, () => 42); | ||
} | ||
|
||
private async Task WaitFor(Func<bool> predicate) | ||
{ | ||
for (var i = 0; i < 100; i++) | ||
{ | ||
if (predicate()) | ||
{ | ||
return; | ||
} | ||
|
||
await Task.Delay(1); | ||
} | ||
|
||
throw new TimeoutException(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
using System; | ||
using System.Linq; | ||
using System.Threading; | ||
using Uno.Extensions.Reactive; | ||
|
||
namespace Uno.Extensions.Reactive.Logging; | ||
|
||
internal static class LogHelper | ||
{ | ||
public static string GetIdentifier(object? obj) | ||
=> obj switch | ||
{ | ||
null => "--null--", | ||
#if DEBUG | ||
_ => $"{GetTypeName(obj)}-{obj.GetHashCode():X8}", | ||
#else | ||
_ => obj.ToString() | ||
#endif | ||
}; | ||
|
||
public static string GetTypeName(object obj) | ||
=> obj.GetType() switch | ||
{ | ||
{ IsGenericType: true } type => $"{type.Name}<{string.Join(", ", type.GenericTypeArguments.Select(GetTypeName))}>", | ||
{ IsArray: true } type => $"{GetTypeName(type.GetElementType()!)}[]", | ||
{ IsValueType: true } type => type.ToString(), | ||
{ } type => type.Name | ||
}; | ||
} |