Task.Continue Using a method requires a task argument?

I have a class with two methods: Load () and Process (). I want to be able to run them separately as background tasks or sequentially. I like the syntax of ContinueWith (), but I can't get it to work. I have to accept the Task parameter in the method that I continue and cannot have the Task parameter for the original method.

I would like to do this without lambda expressions, but am I stuck or using them, forcing a task parameter on one of the methods or creating a third LoadAndProcess () method?

void Run() { // doesn't work, but I'd like to do it //Task.Factory.StartNew(MethodNoArguments).ContinueWith(MethodNoArguments); Console.WriteLine("ContinueWith"); Task.Factory.StartNew(MethodNoArguments).ContinueWith(MethodWithTaskArgument).Wait(); Console.WriteLine("Lambda"); Task.Factory.StartNew(() => { MethodNoArguments(); MethodNoArguments(); }).Wait(); Console.WriteLine("ContinueWith Lambda"); Task.Factory.StartNew(MethodNoArguments).ContinueWith(x => { MethodNoArguments(); }).Wait(); } void MethodNoArguments() { Console.WriteLine("MethodNoArguments()"); } void MethodWithTaskArgument(Task t = null) { Console.WriteLine("MethodWithTaskArgument()"); } 
+6
source share
2 answers

In all ContinueWith() overloads, the first parameter is the delegate that accepts the Task , so you cannot pass it without parameters.

I think that using lambdas is absolutely wonderful and that it will not affect readability. And the lambda in your code is too detailed:

 Task.Factory.StartNew(MethodNoArguments).ContinueWith(_ => MethodNoArguments()) 

Or, as Corey Carson pointed out in a comment, you can write an extension method:

 public static Task ContinueWith(this Task task, Action action) { return task.ContinueWith(_ => action()); } 
+12
source

Writing clean code using multiple continuations is not easy, although you can follow several rules to clear the code:

  • Use shorter form from svick answer
  • Avoid the continuation chain. Store the result of each continuation in a separate variable, and then call ContinueWith on a separate line
  • If the continuation code is long, save it in the lambda variable and then ContinueWith the lambda.
  • Use an extension method like this " Then " to make your code even cleaner.

You can change your code to something like this, which is a little cleaner:

  var call1=Task.Factory.StartNew(()=>MethodNoArguments()); var call2 = call1.ContinueWith(_ => MethodNoArguments()); call2.Wait(); 

or even

  var call1 = Task.Factory.StartNew<Task>(MethodNoArguments); var call2 = call1.Then(MethodNoArguments); call2.Wait(); 

Stephen Tuub discusses the Then extension and other ways to clean up your code in Processing Asynchronous Task Sequences

In C # 4, this problem is solved forever. In C # 5, you can use the async / await keywords to create clean code that looks like the original synchronous version, for example:

  static async Task Run() { await MethodNoArguments(); await MethodNoArguments(); } static async Task MethodNoArguments() { await Task.Run(()=>Console.WriteLine("MethodNoArguments()")); } 

Visual Studio 11 and .NET 4.5 have a Go Live license, so you might start using them right away.

You can use Async CTP in C # 4 to achieve the same result. You can use Async CTP in production, as it has a go go license. The downside is that you will have to make small changes to your code when upgrading to .NET 4.5 due to differences between CTP and .NET 4.5 (for example, CTP has TaskEx.Run instead of Task.Run).

+4
source

Source: https://habr.com/ru/post/915956/


All Articles