在Task.Run中动态

萨拉斯

我有一个长期运行的任务,在不相关的类中具有相同的名称。我试图使用动态的通用方法编写此代码。我收到以下错误

用户代码未处理Microsoft.CSharp.RuntimeBinder.RuntimeBinderException Message =无法将类型'void'隐式转换为'object'

我试图将代码隔离到以下内容

class Program
{
    static void Main(string[] args)
    {
        MainAsync();
        Console.ReadKey();
    }
    static async void MainAsync()
    {
        var classA = new ClassA();
        var classB = new ClassB();
        await RunTask1(classA);
        await RunTask1(classB);
        await RunTask(classA);
        await RunTask(classB);
    }
    static async Task RunTask(dynamic val)
    {
        await Task.Run(() => val.CommonLongRunningTask());
    }
    static async Task RunTask1(ClassA val)
    {
        await Task.Run(() => val.CommonLongRunningTask());
    }
    static async Task RunTask1(ClassB val)
    {
        await Task.Run(() => val.CommonLongRunningTask());
    }
}
internal class ClassA
{
    public void CommonLongRunningTask()
    {
        Console.WriteLine("Class A CommonLongRunningTask");
    }
}
internal class ClassB
{
    public void CommonLongRunningTask()
    {
        Console.WriteLine("Class B CommonLongRunningTask");
    }
}

如果我通过对象本身(RunTask1)而不是动态对象,它将起作用。我试图了解动态传递时发生的情况。

彼得·里奇

我还无法将其追溯到该语言中的某些内容,但是看来您无法使用带有动态表达式的表达式lambda。 更新:无论是否存在void方法调用,涉及a的表达式dynamic始终为类型dynamic,请参见语言方面更新

声明lambda起作用:

private static async Task RunTask(dynamic val)
{
    await Task.Run(() =>
    {
        val.CommonLongRunningTask();
    });
}

更新:

实际上,这里发生的是编译器遇到此情况时:

() => val.CommonLongRunningTask()

它解释为等同于:

() => {return val.CommonLongRunningTask();}

...因为在编译时它不知道您调用的任何内容val都不会返回任何内容。在运行时,它遇到val.CommonLongRunningTask()类型为表达式的表达式void但是return即使对于最低的公分母也不能达到该值object,因此抛出异常并显示消息Cannot implicitly convert type 'void' to 'object'

如果重新编写RunTask如下代码,则您将有一个完全相同的例外

    private static async Task RunTask(dynamic val)
    {
        await Task.Run(() =>
        {
            return val.CommonLongRunningTask();
        });
    }

语言方面

经过更多的研究/讨论,C#规范的7.5.2节详细说明了为什么会发生这种情况。本质上,任何涉及动态的东西本身就是动态类型(因为在编译时编译器无法知道事物将如何绑定),因此将“ val.CommonLongRunningTask()”视为返回动态的东西(因此会出现运行时错误)当它意识到在运行时是无效的时)。

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

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

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Task.Run中的奇怪行为

来自分类Dev

在 Task.Run() 中未抛出 AggregateException

来自分类Dev

替代Task.Run

来自分类Dev

替代Task.Run

来自分类Dev

Task.FromResult()与Task.Run()

来自分类Dev

触发并忘记异步Task与Task.Run

来自分类Dev

触发并忘记异步Task与Task.Run

来自分类Dev

要Task.Run还是不去Task.Run

来自分类Dev

_ = Task.Run与异步void | Task.Run与异步子

来自分类Dev

Task.Run(()MethodName())并等待Task.Run(async()=> MethodName())

来自分类Dev

等待Task.Run与等待

来自分类Dev

Task.Run-处理异常

来自分类Dev

Chef : Opsworks : run rake task

来自分类Dev

task.run异步方法中的空引用错误

来自分类Dev

Task.Run在静态初始化程序中

来自分类Dev

将Task.Run用于服务中的同步方法

来自分类Dev

异步/等待与Task.Run在C#中

来自分类Dev

异步方法中的Task.Run()导致线程池不足?

来自分类Dev

task.run中的异步更新列表框

来自分类Dev

将Task.Run用于服务中的同步方法

来自分类Dev

在 Task.Run 中包装 IO 绑定的异步方法

来自分类Dev

Task.Run与Task.Factory.StartNew的返回类型

来自分类Dev

Task.Run()是否与创建Task实例,然后与Start()相同?

来自分类Dev

Task.ContinueWith() 在 Task.Run() 之后不起作用

来自分类Dev

动态链接`Task <T>`而不阻塞线程

来自分类Dev

使用cy.task动态创建测试

来自分类Dev

PCL中的Task.WhenAll

来自分类Dev

$ input-> getCmd('task')在JOOMLA中是什么'task'

来自分类Dev

在Task#onSucceeded中调用Task#get安全吗?