Add `RealmAccess.WriteAsync` method

This commit is contained in:
Dean Herbert 2022-03-01 18:31:33 +09:00
parent 7fa5842783
commit 9a117467b5
2 changed files with 41 additions and 0 deletions

View File

@ -4,8 +4,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Extensions;
using osu.Game.Beatmaps;
using osu.Game.Rulesets;
using osu.Game.Tests.Resources;
@ -18,6 +20,33 @@ namespace osu.Game.Tests.Database
[TestFixture]
public class RealmSubscriptionRegistrationTests : RealmTest
{
[Test]
public void TestSubscriptionWithAsyncWrite()
{
ChangeSet? lastChanges = null;
RunTestWithRealm((realm, _) =>
{
var registration = realm.RegisterForNotifications(r => r.All<BeatmapSetInfo>(), onChanged);
realm.Run(r => r.Refresh());
// Without forcing the write onto its own thread, realm will internally run the operation synchronously, which can cause a deadlock with `WaitSafely`.
Task.Run(async () =>
{
await realm.WriteAsync(r => r.Add(TestResources.CreateTestBeatmapSetInfo()));
}).WaitSafely();
realm.Run(r => r.Refresh());
Assert.That(lastChanges?.InsertedIndices, Has.One.Items);
registration.Dispose();
});
void onChanged(IRealmCollection<BeatmapSetInfo> sender, ChangeSet? changes, Exception error) => lastChanges = changes;
}
[Test]
public void TestSubscriptionWithContextLoss()
{

View File

@ -8,6 +8,7 @@
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Development;
using osu.Framework.Input.Bindings;
@ -270,6 +271,17 @@ public void Write(Action<Realm> action)
}
}
/// <summary>
/// Write changes to realm asynchronously, guaranteeing order of execution.
/// </summary>
/// <param name="action">The work to run.</param>
public async Task WriteAsync(Action<Realm> action)
{
total_writes_async.Value++;
using (var realm = getRealmInstance())
await realm.WriteAsync(action);
}
/// <summary>
/// Subscribe to a realm collection and begin watching for asynchronous changes.
/// </summary>