[英]Realm doesn’t work with xUnite and .net core
我在使用xUnite和Net core運行領域時遇到問題。 這是一個我想要運行的非常簡單的測試
public class UnitTest1
{
[Scenario]
public void Test1()
{
var realm = Realm.GetInstance(new InMemoryConfiguration("Test123"));
realm.Write(() =>
{
realm.Add(new Product());
});
var test = realm.All<Product>().First();
realm.Write(() => realm.RemoveAll());
}
}
我在不同的機器(Windows和Mac)上獲得了不同的異常,我嘗試使用InMemoryConfiguration創建Realm instace。 在Mac上,我得到以下異常
libc++abi.dylib: terminating with uncaught exception of type realm::IncorrectThreadException: Realm accessed from incorrect thread.
在Windows上,我在運行時遇到以下異常
ERROR Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. at
System.Net.Sockets.NetworkStream.Read(Span1 destination) at
System.Net.Sockets.NetworkStream.ReadByte() at
System.IO.BinaryReader.ReadByte() at
System.IO.BinaryReader.Read7BitEncodedInt() at
System.IO.BinaryReader.ReadString() at
Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.LengthPrefixCommunicationChannel.NotifyDataAvailable() at
Microsoft.VisualStudio.TestPlatform.CommunicationUtilities.TcpClientExtensions.MessageLoopAsync(TcpClient client, ICommunicationChannel channel, Action1 errorHandler, CancellationToken cancellationToken) Source: System.Net.Sockets HResult: -2146232800 Inner Exception: An existing connection was forcibly closed by the remote host HResult: -2147467259
我正在使用Realm 3.3.0和xUnit 2.4.1我已經嘗試降級到Realm 2.2.0,但它也沒有用。
這段代碼幫助我解決了這個問題
Realm GetInstanceWithoutCapturingContext(RealmConfiguration config)
{
var context = SynchronizationContext.Current;
SynchronizationContext.SetSynchronizationContext(null);
Realm realm = null;
try
{
realm = Realm.GetInstance(config);
}
finally
{
SynchronizationContext.SetSynchronizationContext(context);
}
return realm;
}
雖然我花了一段時間才將其應用到我的解決方案中。 首先,我不是將上下文設置為null
,而是使用Nito.AsyncEx.AsyncContext。 因為否則自動更改不會通過線程傳播,因為域需要非空的SynchronizationContext
才能使該功能正常工作。 所以,在我的情況下,該方法看起來像這樣
public class MockRealmFactory : IRealmFactory
{
private readonly SynchronizationContext _synchronizationContext;
private readonly string _defaultDatabaseId;
public MockRealmFactory()
{
_synchronizationContext = new AsyncContext().SynchronizationContext;
_defaultDatabaseId = Guid.NewGuid().ToString();
}
public Realm GetRealmWithPath(string realmDbPath)
{
var context = SynchronizationContext.Current;
SynchronizationContext.SetSynchronizationContext(_synchronizationContext);
Realm realm;
try
{
realm = Realm.GetInstance(new InMemoryConfiguration(realmDbPath));
}
finally
{
SynchronizationContext.SetSynchronizationContext(context);
}
return realm;
}
}
此外,這修復了許多失敗的單元測試。 但我仍然收到同樣的異常 - 從不正確的線程訪問Realm。 我不知道為什么,因為一切都設置正確。 然后我發現失敗的測試與我使用async realm api的方法有關,特別是realm.WriteAsync
。 經過一些挖掘后,我在領域文檔中找到了以下幾行。
如果設置了
SynchronisationContext.Current
,則不會出現問題,但會導致WriteAsync再次在線程池上調度,這可能會創建另一個工作線程。 因此,如果您在線程中使用Current
,請考慮只調用Write
而不是WriteAsync
。
在我的代碼中,沒有直接需要使用異步API。 我刪除並替換為同步Write
,所有測試再次變為綠色! 我想如果我發現自己確實需要使用異步API,因為某種大量插入,我要么模擬那個特定的API,要么用我自己的后台線程替換使用Task.Run
而不是使用Realm的版。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.