簡體   English   中英

如果從未返回await任務,異步方法是否同步?

[英]Is async method synchronous if await Task is never returned?

我有一個在WPF應用程序中的UI線程上調用的構造函數。 在它內部,它調用async方法,但是必須以同步方式完成。 所以我試圖打電話給wait,但是造成了僵局,我明白原因。 因此,我介紹了表明方法應以異步還是同步方式運行的參數。 像這樣:

// constructor that is called on UI thread
public MyClass()
{
    Method1(false).Wait();
}

public async Task Method1(bool runAsync)
{
    await Method2(runAsync);
}

public async Task Method2(bool runAsync)
{
    if (runAsync)
    {
        await Task.Run(() => Thread.Sleep(1000));
    }
    else
    {
        Thread.Sleep(1000);
    }
}

我不想使用ConfigureAwait,因為我希望一切都在UI線程上運行。 將Method1(false).Wait(); 會導致死鎖(使用安全嗎)? 我測試了很多,但沒有測試,但是我不確定。 最后,我真正的問題是:如果從未執行過“ await Task.Run(...”),那么我的方法是否完全同步呢?我找到了與此主題相關的幾篇文章,但沒有一篇直接回答我的問題。

我有一個在WPF應用程序中的UI線程上調用的構造函數。 在它內部,它調用async方法,但是必須以同步方式完成。

我要在那里阻止你。 最好的解決方案是不要在UI線程上運行同步/阻塞代碼。 這會降低您的用戶體驗。 相反,您應該重組代碼,以使您永遠不會處於這種情況。

當顯示UI時,UI框架會要求您的代碼顯示數據。 您的代碼應同步運行並立即返回 (不阻塞)。 但是您的代碼還需要執行一些異步工作才能顯示數據。 因此那里存在沖突。

解決方案是為UI設計一種中間狀態,例如“正在加載...”消息或微調框。 然后,當您的代碼啟動時,它可以同步/立即顯示“正在加載”狀態(並啟動異步操作),並且當異步數據到達時,代碼會將 UI 更新為“最終”狀態。

我將在關於異步MVVM數據的文章中更詳細地討論這種模式。

與其在構造時花費大量精力解決異步問題(您的阻塞解決方案不是很好),何不編寫一個異步工廠來噴出這些對象呢?

class MyClass
{
    public MyClass()
    {

    }

    public async Task Method2(bool runAsync)
    {
        //async immediately
        await Task.Delay(1000); //no Thread.Sleep. Blocking code != good
    }
}

然后

public MyClassFactory
{
    public async Task<MyClass> GetAsync()
    {
        var c = new MyClass();
        await c.Method2();
        return c;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM