C# 使用 Action<T> 创建任务

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13046232/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 01:27:34  来源:igfitidea点击:

Create a Task with an Action<T>

c#.nettask-parallel-library

提问by alwayslearning

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

我正在尝试创建一个 System.Threading.Tasks.Task 实例来执行接受某种类型参数的操作。我以为我可以做类似的事情

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.

显然这不能编译。看来我只能对任务使用 anAction<object>而不是 an Action<T>,然后在我的方法中将“对象”转换为 T 。

How can I achieve what I want most effectively and efficiently?

我怎样才能最有效和最高效地实现我想要的?

回答by MartinStettner

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 Contravarianceto achieve your goal without introducing a new delegate

如果您使用 .NET 4.0 或更高版本,则可以使用逆变来实现您的目标,而无需引入新的委托

//INCORRECT Code, casts InvalidCastException at runtime
Action action = DoWork;
Task task = new Task((Action)action, obj);
//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 Covariancein this case.

感谢@svick 指出,第二个选项是不正确的:我太忙于整理,我监督的 Action 是协变还是逆变(实际上是逆变的,至少我是对的),那在这种情况下,我需要协方差

Contravariance means that you can do

逆变意味着你可以做到

Action<object> action1 = someAction;
Action<SubClass> action2 = action1;

without explicit casting.

没有显式转换。

回答by cuongle

You also can use directly:

也可以直接使用:

MyClass obj = new MyClass();
Task task = Task.Run(() => DoWork(obj));