【问题标题】:Using Tasks : ContinueWith needs a return statement which my business logic doesn't require使用任务:ContinueWith 需要我的业务逻辑不需要的 return 语句
【发布时间】:2015-04-22 17:05:48
【问题描述】:

我昨天开始在我的一个小项目中使用 Tasks。在代码中设置好任务逻辑后,我意识到我不得不在 ContinueWith() 函数中使用 return 语句。

即使myTask 首先需要返回一个对象,有什么方法可以避免在 ContinueWith 中返回?

Task<List<Object>> myTask = Task<List<Object>>.Factory.StartNew(() =>
{
    //business logic creating an Object to return 
    //return Object created
})
.ContinueWith<List<Object>>((antecedant) =>
{
    //business logic : needs to use antecedant
    return null; //can i get rid of this? I don't need to return an object in this section
}, TaskScheduler.FromCurrentSynchronizationContext());

让我们说 return null 语句让我很烦......

注意:针对 Yuval 的评论,我使用的是 .net framework 4.5

解决方案

根据 CoryNelson 的评论,我想出了这段代码。它完全符合我的需求。

Task<List<Object>> myTask = Task<List<Object>>.Factory.StartNew(() =>
{
    //business logic creating an Object to return 
    //return Object created
});
Task myFollowingTask = myTask.ContinueWith((antecedant) =>
{
    //business logic using antecedant
}, TaskScheduler.FromCurrentSynchronizationContext());

我不再需要 ContinueWith 中的 return 语句了。

Here 是我获取所需信息的地方。见代码示例

【问题讨论】:

  • 有一个重载需要一个动作而不是一个函数。你应该能够摆脱你的回报并让它发挥作用。
  • @Cory Nelson 谢谢,我会查一下!您指的是 ContinueWith 重载,对吗?
  • 那你为什么要Task&lt;List&lt;object&gt;&gt;?为什么不用Task 而不是你不需要返回类型。
  • 因为我需要在 ContinueWith 中使用先行词。 antecedant 将是从 myTask 创建和返回的 >。
  • 您可以将它们分成两个单独的任务。顺便说一句,您使用的是哪个版本的 .NET 框架?

标签: c# .net task-parallel-library


【解决方案1】:

解决问题的两种方法:

任务变量的拆分声明:

Task<List<Object>> myTask = Task<List<Object>>.Factory.StartNew(() =>
{
    //business logic creating an Object to return 
    //return Object created
});

Task taskContinuation = myTask.ContinueWith((antecedant) =>
{
    //business logic : needs to use antecedant
}, TaskScheduler.FromCurrentSynchronizationContext());

这将允许您独立运行这两个任务,其中continuation 的类型为Task

第二个也是更好的 IMO 方法是使用async-await

public async Task CreateFooAsync()
{
    List<object> objects = await Task.Run(() => /* Create object */);
    // here you're on the UI thread, continue execution flow as normal.
}

注意async-await的语义意味着第一个任务将异步等待对象被创建。

【讨论】:

  • 您可以将整体定义设为Task 类型,而无需拆分它们。 StartNew 返回 Task&lt;List&lt;Object&gt;&gt; 的事实并不能阻止 myTask 成为 Task,因为它是由 ContinueWith 的类型定义的。
  • @Guvante 我认为他希望返回的List&lt;object&gt;Task 之外可以访问。如果类型是普通的Task,那将不起作用。
【解决方案2】:

如果您想在任务之外访问结果,则需要将该结果提供给myTask 的输出。

Task<List<Object>> myTask = Task<List<Object>>.Factory.StartNew(() =>
{
    //business logic creating an Object to return 
    //return Object created
})
.ContinueWith((antecedant) =>
{
    //business logic : needs to use antecedant
    return antecedant.Result;
}, TaskScheduler.FromCurrentSynchronizationContext());

这将导致myTask.ResultContinueWith 中的antecedant.Result 相同。

【讨论】:

  • 这不会编译。 myTask 需要来自 ContinueWith 的返回类型,而您没有提供。
  • @YuvalItzchakov:只是错过了调整myTask 的类型,在这种情况下它是一个非泛型Task(因为整个任务不需要返回类型)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-12-22
  • 1970-01-01
  • 2017-08-11
  • 1970-01-01
  • 2022-12-24
  • 1970-01-01
  • 2021-03-28
相关资源
最近更新 更多