我不確定如何理解以下觀察結果。Task.Run和預期的代理
var f = new Func<CancellationToken,string>(uc.ViewModel.SlowProcess);
1) (VALID) string dataPromise = await Task.Run<string>(() => f(token), token);
2) (VALID) string dataPromise = await Task.Run<string>(() => uc.ViewModel.SlowProcess(token), token);
3) (ERROR) string dataPromise = await Task.Run<string>(f(token), token);
uc.ViewModel.SlowProcess是需要的CancellationToken作爲參數,並返回字符串的方法。
項目1)和2)有效且正常工作。項目3)無效,給出以下錯誤:
錯誤1'System.Threading.Tasks.Task.Run(System.Func>,System.Threading.CancellationToken)'的最佳重載方法匹配有一些無效參數
錯誤2參數1:不能從「字串」到「System.Func>」
爲何無法通過F(令牌)作爲代表轉換?如果我用一個不帶參數的方法來做,它也可以。
感謝。我知道你說的是正確的,但f是Func的一個實例,所以它是一個委託。好像你需要將委託包裝在一個委託中(即,將f包裝在lambda中)以使其正確工作。似乎應該有一種方法來傳遞f而不用將它包裝在lambda中。 – Bill 2014-12-05 04:38:33
@Bill:再看看代碼'Task.Run(f(token),token)'。正如弗蘭克所說,代碼'f(token)'不會傳遞'f'作爲代表;它*調用*'f'。如果你想通過'f'作爲委託,你必須執行'Task.Run (f,token)'。 –
2014-12-05 13:32:59
@Stephen:是的,同意了。所以,lambda表達式工作的原因是在(1)中,由於賦予給f的參數,lambda基本上包裝了函數uc.ViewModel.SlowProcess - 就像在(2)中一樣。當f被參數化時,它就像它所包裝的函數一樣對待,而當它只是f時,它被視爲一個del的引用。如果我創建了一個多播委託multiF,()=> multiF(token)也可以。一旦你接受傳遞一個參數化的委託本質上得到像傳遞函數一樣的對待,那麼所有的工作就像你期望的那樣。 IL代碼可能顯示所有。 – Bill 2014-12-05 15:57:57