2015-05-22 42 views
4

要使用此方法:如何使用Task.Run(Func <Task> f)方法簽名?

public static Task Run(Action action) 

我只是寫:

void MyMethod(){ //do something } 
Task t = Task.Run(new Action(MyMethod)); 

但是我不知道如何使用以下過載

public static Task Run(Func<Task> f) 

在MSDN中提到,返回的任務是「由f返回的任務 的代理」,這對我更加困惑。代理是什麼意思,我怎麼稱呼這個方法?

回答

1

Func<T>是一個通用的委託 - 這裏是它的全部簽名:

public delegate TResult Func<out TResult>() 

正如你所看到的,它代表了一個函數,它沒有參數,返回TResult類型的實例。在Func<Task>的情況下,TResultTask

這意味着什麼,是你可以這樣做:

public Task MyAsyncMethod() { ... } 

Task.Run(MyAsyncMethod); 

這是你的方法MyAsyncMethod轉換成Func<Task>類型的委託,並把它傳遞給Task.Run。它是Task.Run(new Func<Task>(MyAsyncMethod));

語法糖在MSDN中提到,返回的任務是這更加迷惑我「爲用f返回任務的代理」(什麼是代理的意思?)

這意味着Task.Run將簡單地包裝由MyAsyncMethod返回的任務是另一個Task

5

Func<Task>只是一個功能,返回的任務。 然後執行任務。

因此Task Run(Func<Task> f)返回一個Task,其作業是運行另一個Task(由f創建的那個)。 這就是「代理」是什麼意思。

然而,閱讀注意事項MSDN(強調):

Run<TResult>(Func<Task<TResult>>)方法是使用語言編譯器支持asyncawait關鍵字。 它並不打算直接從用戶代碼中調用。

0
一個

Func<T>指返回T,在這種情況下是一個Task的方法。因此,爲了使MyMethod這個特殊超載兼容,你會寫

Task MyMethod() {...} 

這也意味着你可以做MyMethodasync方法,從而

async Task MyMethod() {...} 

當提到「代理」,這意味着由Task.Run返回的Task實際上並不是由MyMethod返回的任務,而是包裝它。

1

該簽名允許您在運行Task.Run時提供返回任務的方法。這是因爲Func<T>的最後一個通用參數是您提供的代表給出的返回值。含義:

public Func<bool> IsValid = this.ValidateUser; 
public bool ValidateUser() { return someUser.IsAuthenticated; } 

甚至只是

public Func<bool> IsValidUser = this.User.IsAuthenticated; 

然後你可以使用委託,就像任何其他的方法,並委託將返回一個bool。

public void Foo() 
{ 
    if (!IsValidUser()) throw new InvalidOperationException("Invalid user"); 
} 

通過提供除返回值之外的其他泛型類型,您可以使用傳遞給委託的參數。

Func<int, bool> IsUserAgeValid = (age) => return age > 18; 

// Invoke the age check 
bool result = this.IsUserAgeValid(17); 

需要記住的是最後一個泛型總是Func中的返回類型。如果只提供了一個通用類型,那麼沒有參數,只有返回類型。

A Func<Task>允許您在您的Task.Run調用中使用awaitable方法。 這也意味着您可以在您提供的匿名代理內部await

public Task Foo() 
{ 
    /* .. do stuff */ 
} 

public void Bar() 
{ 
    Task.Run(async() => 
     { 
      await Foo(); 
      /* do additional work */ 
     }); 
} 

,如果你不需要等待調用Foo(),你可以給Task.RunFoo方法。

Task.Run(Foo); 

如果你發現自己想等待如上圖所示給Task.Run的awaitable方法,它可能是更好您使用ContinueWith

public void Bar() 
{ 
    Task.Run(Foo).ContinueWith(foosTaskResult => 
    {  
     /* Do stuff */ 
    }); 
} 

MSDN文檔說的任務返回的是對的˚F的任務代理,基本上意味着

Task returnedTask = Task.Run(Foo); 

將設置returnedTask到是由返回的任務調用等待方法Foo()

相關問題