[c#] Task.Run with Parameter(s)?

I'm working on a multi-tasking network project and I'm new on Threading.Tasks. I implemented a simple Task.Factory.StartNew() and I wonder how can I do it with Task.Run()?

Here is the basic code:

Task.Factory.StartNew(new Action<object>(
(x) =>
{
    // Do something with 'x'
}), rawData);

I looked into System.Threading.Tasks.Task in Object Browser and I couldn't find a Action<T> like parameter. There is only Action that takes void parameter and no type.

There are only 2 things similiar: static Task Run(Action action) and static Task Run(Func<Task> function) but can't post parameter(s) with both.

Yes, I know I can create a simple extension method for it but my main question is can we write it on single line with Task.Run()?

This question is related to c# lambda task-parallel-library task

The answer is


It's unclear if the original problem was the same problem I had: wanting to max CPU threads on computation inside a loop while preserving the iterator's value and keeping inline to avoid passing a ton of variables to a worker function.

for (int i = 0; i < 300; i++)
{
    Task.Run(() => {
        var x = ComputeStuff(datavector, i); // value of i was incorrect
        var y = ComputeMoreStuff(x);
        // ...
    });
}

I got this to work by changing the outer iterator and localizing its value with a gate.

for (int ii = 0; ii < 300; ii++)
{
    System.Threading.CountdownEvent handoff = new System.Threading.CountdownEvent(1);
    Task.Run(() => {
        int i = ii;
        handoff.Signal();

        var x = ComputeStuff(datavector, i);
        var y = ComputeMoreStuff(x);
        // ...

    });
    handoff.Wait();
}

From now you can also :

Action<int> action = (o) => Thread.Sleep(o);
int param = 10;
await new TaskFactory().StartNew(action, param)

Idea is to avoid using a Signal like above. Pumping int values into a struct prevents those values from changing (in the struct). I had the following Problem: loop var i would change before DoSomething(i) was called (i was incremented at end of loop before ()=> DoSomething(i,ii) was called). With the structs it doesn't happen anymore. Nasty bug to find: DoSomething(i, ii) looks great, but never sure if it gets called each time with a different value for i (or just a 100 times with i=100), hence -> struct

struct Job { public int P1; public int P2; }
…
for (int i = 0; i < 100; i++) {
    var job = new Job { P1 = i, P2 = i * i}; // structs immutable...
    Task.Run(() => DoSomething(job));
}

Just use Task.Run

var task = Task.Run(() =>
{
    //this will already share scope with rawData, no need to use a placeholder
});

Or, if you would like to use it in a method and await the task later

public Task<T> SomethingAsync<T>()
{
    var task = Task.Run(() =>
    {
        //presumably do something which takes a few ms here
        //this will share scope with any passed parameters in the method
        return default(T);
    });

    return task;
}

Use variable capture to "pass in" parameters.

var x = rawData;
Task.Run(() =>
{
    // Do something with 'x'
});

You also could use rawData directly but you must be careful, if you change the value of rawData outside of a task (for example a iterator in a for loop) it will also change the value inside of the task.


I know this is an old thread, but I wanted to share a solution I ended up having to use since the accepted post still has an issue.

The Issue:

As pointed out by Alexandre Severino, if param (in the function below) changes shortly after the function call, you might get some unexpected behavior in MethodWithParameter.

Task.Run(() => MethodWithParameter(param)); 

My Solution:

To account for this, I ended up writing something more like the following line of code:

(new Func<T, Task>(async (p) => await Task.Run(() => MethodWithParam(p)))).Invoke(param);

This allowed me to safely use the parameter asynchronously despite the fact that the parameter changed very quickly after starting the task (which caused issues with the posted solution).

Using this approach, param (value type) gets its value passed in, so even if the async method runs after param changes, p will have whatever value param had when this line of code ran.


Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to lambda

Java 8 optional: ifPresent return object orElseThrow exception How to properly apply a lambda function into a pandas data frame column What are functional interfaces used for in Java 8? Java 8 lambda get and remove element from list Variable used in lambda expression should be final or effectively final Filter values only if not null using lambda in Java8 forEach loop Java 8 for Map entry set Java 8 Lambda Stream forEach with multiple statements Java 8 stream map to list of keys sorted by values Task.Run with Parameter(s)?

Examples related to task-parallel-library

What is the difference between Task.Run() and Task.Factory.StartNew() Task.Run with Parameter(s)? HttpClient - A task was cancelled? Running multiple async tasks and waiting for them all to complete Deserialize JSON to Array or List with HTTPClient .ReadAsAsync using .NET 4.0 Task pattern Calling async method synchronously How can I tell Moq to return a Task? When to use Task.Delay, when to use Thread.Sleep? Awaiting multiple Tasks with different results How to safely call an async method in C# without await

Examples related to task

Task.Run with Parameter(s)? Return list from async/await method When correctly use Task.Run and when just async-await How to safely call an async method in C# without await My C# application is returning 0xE0434352 to Windows Task Scheduler but it is not crashing Platform.runLater and Task in JavaFX Task vs Thread differences How do I wait until Task is finished in C#? Deleting all pending tasks in celery / rabbitmq Android: Cancel Async Task