[英]Using Func with Task in C#
我在嘗試理解Func
在C#中的確切運作方式時遇到了一些問題,盡管我已經閱讀了一些關於它的好博客。
我有以下場景:我正在構建一個小型計費系統,它使用Azure Service Bus隊列來處理賬單。 用戶可以初始化兩個進程:
為此,我提出了一種初始化計費任務(包含N個賬單)的通用方法,該方法采用bool
參數來判斷是否需要創建日記本或實際賬單。 在這個方法中,我正在運行以下檢查:
if (isDayBookProcessing)
{
// Daybook processing code here
}
else
{
// Run queue process async
StartQueueProcess(queueName, billingTaskId, numOfItemsEnqueued);
}
然后我得到了一個通用的“StartQueueProcess”方法,它在它自己的Task
運行,如下所示:
private void StartQueueProcess(string queueName, int billingTaskId, int numOfItemsEnqueued)
{
Task.Factory.StartNew(() => _factory.AzureFactory.ServiceBus.ProcessBillingQueue(queueName, billingTaskId, numOfItemsEnqueued));
}
如您所見, StartQueueProcess
方法在我的ServiceBus
類上運行ProcessBillingQueue
方法,這意味着它無法運行ProcessDaybookQueue
我最初想的是只使用Func<string, int, int, bool>
並使StartQueueProcess
方法返回一個bool(因為Func
需要返回一些東西),使它看起來像這樣:
if (isDayBookProcessing)
{
// Daybook processing code here
StartQueueProcess(_factory.AzureFactory.ServiceBus.ProcessDaybookQueue(queueName, billingTaskId, numOfItemsEnqueued));
}
else
{
// Run queue process async
StartQueueProcess(_factory.AzureFactory.ServiceBus.ProcessBillingQueue(queueName, billingTaskId, numOfItemsEnqueued));
}
private bool StartQueueProcess(Func<string, int, int, bool> processMethod)
{
Task.Factory.StartNew(() => processMethod);
return true;
}
但是,這會給出一個錯誤,告訴我Argument type 'void' is not assignable to parameter type 'System.Func<string, int, int bool>'
我的_factory.AzureFactory.ServiceBus.ProcessDaybookQueue(queueName, billingTaskId, numOfItemsEnqueued)
返回void。 使它返回Func<string, int, int, bool>
沒有錯誤。 但為什么呢? 我不應該能夠讓它返回我想要的東西(即無效)嗎?
任何人都可以對此有所了解嗎? :-)
你不需要一個Func
,你需要一個Action
。 Func
是您的委托具有返回值的時間。 沒有返回值時, Action
適合:
private void StartQueueProcess(Action<string, int, int> processMethod)
{
Task.Factory.StartNew(() => processMethod);
}
請注意,將異步重疊包裝為反模式 。 您最好在呼叫站點使用Task.Run
:
if (isDayBookProcessing)
{
// Daybook processing code here
Task.Run(() => _factory.AzureFactory.ServiceBus.ProcessDaybookQueue(
queueName,
billingTaskId,
numOfItemsEnqueued));
}
else
{
// Run queue process async
Task.Run(() => _factory.AzureFactory.ServiceBus.ProcessBillingQueue(
queueName,
billingTaskId,
numOfItemsEnqueued));
}
雖然我看到你正在調用相同的方法,所以我認為不需要if-else
。
我看到兩個不同的問題:1。我擔心Task.Factory.StartNew(() => processMethod)
不會按預期執行。 它不會執行processMethod
。 2. StartQueueProcess
被定義為接受具有三個參數的Func <>函數。 它沒有提到參數本身。 你有責任為這個lambda提供一些參數。
你為什么假設你需要在這里使用Func<>
? 你不必。 你的StartQueueProcess
可以像這樣:
private bool StartQueueProcess(
string param1,
int param2,
int param3,
Action<string, int, int> processMethod)
{
Task.Factory.StartNew(() => processMethod(param1, param2, param3));
}
例如,這個StartNew重載將很樂意接受任何Action參數)。
而且,在這個特殊情況下,我認為根本不需要聲明一個新函數。 一個簡單的.StartNew
調用可能會很好(盡管它很接近):
if (isDayBookProcessing)
{
// Daybook processing code here
Task.Factory.StartNew(() => _factory
.AzureFactory
.ServiceBus
.ProcessDaybookQueue(queueName, billingTaskId, numOfItemsEnqueued));
}
else
{
// Run queue process async
Task.Factory.StartNew(() => _factory
.AzureFactory
.ServiceBus
.ProcessBillingQueue(queueName, billingTaskId, numOfItemsEnqueued));
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.