![](/img/trans.png)
[英]Nunit 3.12.0 missing [RequiresSTA] in WPF view model unit test. The calling thread must be STA
[英]NUnit async test + RequiresSTA => await not returning on STA thread
下面的代碼:
[RequiresSTA]
[Test]
public async Task TestSta()
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId+" - "+Thread.CurrentThread.GetApartmentState());
// *** await something here ***
Console.WriteLine(Thread.CurrentThread.ManagedThreadId+" - "+Thread.CurrentThread.GetApartmentState());
new FrameworkElement();
}
產生以下輸出:
9-STA
12-MTA
然后,在新的FrameworkElement()上引發InvalidOperationException。
NUnit支持STA線程創建,現在支持異步測試,但是它似乎沒有通過創建MTA SynchronizationContext來混合兩種模式。
我該如何工作? 任何解決方法?
您可以使用我的AsyncEx
庫中的AsyncContext
,該庫最初是為支持async
單元測試而編寫的,然后再由單元測試庫支持。
[RequiresSTA]
[Test]
public Task TestSta()
{
AsyncContext.Run(async () =>
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId+" - "+Thread.CurrentThread.GetApartmentState());
// *** await something here ***
Console.WriteLine(Thread.CurrentThread.ManagedThreadId+" - "+Thread.CurrentThread.GetApartmentState());
new FrameworkElement();
});
}
我設法解決了這個問題。 但是,我敢肯定,關於stackoverflow的帖子會避免我很頭疼:)參見下面的答案。
一篇關於SynchronizationContext的非常好的文章(單擊此處)只是給了我所需的代碼(和知識)。
但是,我必須對其進行一些調整,以避免在StaSynchronizationContext處置方面出現死鎖,並在工作線程內部傳播同步上下文。
我的測試現在如下所示:
[Test]
[RequiresSTA]
public async Task DoSomeUITest()
{
using (new StaSynchronizationContext())
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId + " - " + Thread.CurrentThread.GetApartmentState());
// *** await something here ***
Console.WriteLine(Thread.CurrentThread.ManagedThreadId + " - " + Thread.CurrentThread.GetApartmentState());
new FrameworkElement();
}
}
現在輸出:
9-STA
12-STA
... 問題解決了 !
*編輯和免責聲明*在等待之前,您的代碼將在NUnit創建的STA線程上運行。 (線程9)第一次等待后,代碼將在StaSynchronizationContext創建的線程(線程12)上運行:即使它們都是STA, 它們也不是同一線程
在等待之前要提防實例化控件,然后再使用它們。 只是需要更多的調整才能直接切換到主線程(我們可以想象一個“ using(await StaSynchronizationContext.Create())”,這將使我們在開始時打開線程12)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.