处理动作和任务

风格

我想传递一个返回void并接受param int的方法我怎么做?

有人可以告诉我非lambda和lambda版本吗?

        private void LongTask(int s)
        {

            Thread.Sleep(s* 1000);
        }


        public void Run()
        {
            Task q = Task.Run(Action<int>(LongTask));

        }
彼得·杜尼奥

在您的示例中,您没有显示要传递给该方法的值。很难确定您要问的是什么。但是我您正在要求说明如何调用您的方法LongTask(),为Task.Run()操作传递适当的值,并同时使用lambda语法和非lambda语法提供此说明。

注意:实际上,这几乎是特定于的Task.Run()这在您将委托传递给方法的任何时候都适用,其中委托需要代表一种方法,该方法的签名与所调用方法所使用的签名不同。Task.Run()是参与这里几乎是偶然的。

反正…

实际上,由于lambda表达式(在此用法中)可编译为匿名方法,因此实际上有三个选择:

“老派”匿名方法:

public void Run()
{
    int someValue = 17;

    Task q = Task.Run(delegate { LongTask(someValue); });
}

上面的代码使编译器创建一个匿名方法(delegate() { LongTask(someValue); }),并生成代码以创建传递给该Task.Run()方法的委托实例委托的类型是从用法中推断出来的(即基于与匿名方法声明匹配的一种方法重载)。

Lambda匿名方法:

public void Run()
{
    int someValue = 17;

    Task q = Task.Run(() => LongTask(someValue));
}

除了使用名义上更简洁的lambda语法声明匿名方法外,以上内容与前面的示例相同。我说“名义上”是因为在这种特殊情况下,它实际上并没有那么短。但是在其他情况下,lambda语法更方便。通常,当匿名方法返回值时,由于使用lambda语法,该return语句是隐式的。

显式:

class A
{
    private readonly int _value;
    private readonly Action<int> _action;

    public A(int value, Action<int> action)
    {
        _value = value;
        _action = action;
    }

    public void M() { _action(_value); }
}

public void Run()
{
    int someValue = 17;

    Task q = Task.Run((Action)(new A(someValue, LongTask).M));
}

上面的内容依赖于显式编写的类,其作用与匿名方法选项导致的编译器生成的类的目的相同。根据确切的情况,编译器生成的类在实现上可能会有很大不同。但是其行为本质上是相同的:创建了一个类的实例,在其中存储了所需的值,并且在类中包含了具有适当签名的方法,该方法的主体是您要执行的代码。

(此外:在这种情况下,为简洁起见,我展示了一个实际上使用委托实例的实现,而不是对目标对象和方法调用进行硬编码。实际上,这是比编译器实际生成的可重用的实现,主要是因为编译器必须处理许多更复杂的场景,并且此优化仅在非常狭窄的场景中才有用,即只有一种方法被调用,编译器还将存储this复制匿名主体方法到生成的方法,方法是使用存储的this引用和所需的任何其他捕获的变量(例如,调用该LongTask()方法。)

在上面的变量_valuereadonly,但是在匿名方法中,它们通常是从匿名方法的上下文中捕获的可变变量。为了更好地模拟匿名方法通常如何工作,您需要更多类似这样的东西:

class A
{
    public int value;
    private readonly Action<int> _action;

    public A(int value, Action<int> action)
    {
        this.value = value;
        _action = action;
    }

    public void M() { _action(value); }
}

public void Run()
{
    A a = new A(17, LongTask);

    Task q = Task.Run((Action)a.M);

    a.value = 19;
}

请注意,以上value是公共字段。并且代码实际上在调用后修改了变量Task.Run()这类似于更改someValue匿名方法示例中的值(同样,在调用之后Task.Run()),并且具有相同的风险:如果Task.Run()在任务可以执行方法调用之前执行了方法之后的赋值,那么您将传递不同的值如果任务可以先执行该方法,则返回该方法。

道德:始终当心捕获的变量,并确保它们具有预期的寿命和价值。


顺便说一句,Action在最后两个示例中,需要强制转换为所需的委托类型,因为否则Task.Run(),选择重载在Task.Run(Action)之间对编译器是不明确的Task.Run(Func<Task>)简短版本:尝试从方法组转换为委托类型并将其与特定的重载匹配时,将忽略委托签名的返回类型。有关较长版本,请参见编译器歧义调用错误-匿名方法和带有Func <>或Action的方法组

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

C动作和变量

来自分类Dev

如何在“处理装运”屏幕中添加动作和处理程序?

来自分类Dev

如何使用动作和组件来处理Ember的客户端错误?

来自分类Dev

表单动作和antiCSRF令牌

来自分类Dev

自动完成-动作和onClick

来自分类Dev

Redux:组织容器,组件,动作和Reducer

来自分类Dev

子组件中的导入动作和分派

来自分类Dev

将动作和模型转换为网址

来自分类Dev

Redux:组织容器,组件,动作和Reducer

来自分类Dev

Reactjs - 父、子动作和函数

来自分类Dev

Oozie>异步动作和同步动作有什么区别

来自分类Dev

UIButton具有按下动作和释放动作

来自分类Dev

在recyclerview中区分拖动动作和滑动动作

来自分类Dev

UIButton具有按下动作和释放动作

来自分类Dev

Oozie>异步动作和同步动作有什么区别

来自分类Dev

没有为动作和结果定义结果

来自分类Dev

REST WebAPI-动作和子控制器呢?

来自分类Dev

Cocos2d-动作和动画未暂停

来自分类Dev

Rails中的动作和过滤器之间的区别

来自分类Dev

没有动作和调度程序的助焊剂?

来自分类Dev

Rails控制器中的动作和方法

来自分类Dev

一个TableViewController,多个segue动作和返回

来自分类Dev

古代或未来观察者的岁差,正确动作和时代

来自分类Dev

将动作和插座连接到NIB控制器

来自分类Dev

与react / redux共享动作和减速器

来自分类Dev

新动作和呈现部分注册表单

来自分类Dev

Promise.all处于Redux动作和更新状态

来自分类Dev

Cocos2d-动作和动画未暂停

来自分类Dev

没有为动作和结果定义结果