簡體   English   中英

從屬性設置器調用異步方法

[英]Call async method from property setter

我在幾個地方都可以這樣做,但是重新編寫代碼是不可行/不實際的。 但是,該方法似乎只能被“正常”調用,例如:

set
{
    ...
    DoSomethingAsync();
}

在此行下的VS編輯器中會出現一個花樣,並帶有以下工具提示警告:-

因為不等待此調用,所以在調用完成之前將繼續執行當前方法。

如果沒有async / await關鍵字,我有點希望該方法最終被同步調用。 我什么不來?

如果我將行更改為以下內容,則花粉/警告消失:-

DoSomethingAsync().Wait();

大概這變成了阻塞呼叫?

純粹出於好奇,執行以下操作會有什么意義:

Task.Run(() => DoSomethingAsync());

如果沒有async / await關鍵字,我有點希望該方法最終被同步調用。 我什么不來?

您的假設是錯誤的: async方法始終被異步調用。 除非您使用Wait()它,否則它將不會等到async方法完成。 Wait()確實會阻止對您的異步方法的調用。 即使執行Task.Run ,它也會異步運行(兩次,因為它的async方法在Task.Runasync運行)。

不能異步調用屬性,因此Get方法可以解決問題。 這樣,您就可以使代碼一直處於異步狀態。

在屬性設置器中調用異步方法(MVVM使用)

創建方法

public class AsyncRunner
{
    public static void Run(Task task, Action<Task> onError = null)
    {
        if (onError == null)
        {
            task.ContinueWith((task1, o) => { }, TaskContinuationOptions.OnlyOnFaulted);
        }
        else
        {
            task.ContinueWith(onError, TaskContinuationOptions.OnlyOnFaulted);
        }
    }
}

在setter屬性中調用它

private NavigationMenuItem _selectedMenuItem;
public NavigationMenuItem SelectedMenuItem
{
    get { return _selectedMenuItem; }
    set
    {
        _selectedMenuItem = val;
        AsyncRunner.Run(YourAsyncMethod(_selectedMenuItem));            
    }
}

這是需要運行的異步方法...

private async Task YourAsyncMethod(NavigationMenuItem newNavigationMenu)
{
    //call async tasks...
}

如果您查看DoSomethingAsync()的定義,它將像這樣

   public async Task<T> DoSomethingAsync()
   public       Task<T> DoSomethingAsync()

無論哪種方式,它都將返回(可能)剛剛開始的Task。

您可以在任務上調用.Wait(),也可以不調用。

如果沒有,您將使該任務在后台運行。
那可能不是程序員的意圖-因此是警告。

暫無
暫無

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

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