I somehow feel I am missing something basic. Here's my problem.
I am trying to create a System.Threading.Tasks.Task instance to execute an action that accepts a parameter of a certain type. I thought I could do something like
void DoWork(MyClass obj) {} //My action that accepts a parameter of type 'MyClass'
MyClass obj = new MyClass();
Action<MyClass> action = DoWork; //action that points to the method
Task task = new Task(action,obj); //task that would execute 'DoWork' with 'obj' as the parameter when I call Start.
Obviously this does not compile. It seems I can only use an Action<object>
and not an Action<T>
for a task and then cast the 'object' to T inside my method.
How can I achieve what I want most effectively and efficiently?
The Run method allows you to create and execute a task in a single method call and is a simpler alternative to the StartNew method. It creates a task with the following default values: Its cancellation token is CancellationToken.
To start a task in C#, follow any of the below given ways. Use a delegate to start a task. Task t = new Task(delegate { PrintMessage(); }); t. Start();
A task is an object that represents some work that should be done. The task can tell you if the work is completed and if the operation returns a result, the task gives you the result.
The Task Constructor framework provides a flexible and transparent way to define and plan actions that consist of multiple interdependent subtasks. It draws on the planning capabilities of MoveIt to solve individual subproblems in black-box planning stages.
You also can use directly:
MyClass obj = new MyClass();
Task task = Task.Run(() => DoWork(obj));
You could use
Action<Object> action = o => DoWork((MyClass)o);
Task task = new Task(action, obj);
If you're using .NET 4.0 or above, you can use Contravariance to achieve your goal without introducing a new delegate
//INCORRECT Code, casts InvalidCastException at runtime Action action = DoWork; Task task = new Task((Action)action, obj);
EDIT:
Thanks for @svick for pointing out, that the second option is not correct: I was too busy sorting out, whether Action is co- or contravariant (it is in fact contravariant, I was right about this at least) that I oversaw, that I would need Covariance in this case.
Contravariance means that you can do
Action<object> action1 = someAction;
Action<SubClass> action2 = action1;
without explicit casting.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With