标签: dynamic-invoke

什么是__DynamicallyInvokable属性?

通过System.Linq.Enumerable在DotPeek中查看,我注意到一些方法是使用[__DynamicallyInvokable]属性调整的.

这个属性扮演什么角色?它是由DotPeek添加的还是它扮演另一个角色,也许告诉编译器如何最好地优化方法?

c# dynamic-invoke

169
推荐指数
2
解决办法
2万
查看次数

Invoke和DynamicInvoke之间的区别

委托中的Invoke和DynamicInvoke有什么区别?请给我一些代码示例来解释这两种方法之间的区别.

.net c# delegates invoke dynamic-invoke

123
推荐指数
1
解决办法
4万
查看次数

可以在此通用代码中避免Delegate.DynamicInvoke吗?

这个问题部分是关于代表,部分是关于泛型.

鉴于简化的代码:

internal sealed class TypeDispatchProcessor
{
    private readonly Dictionary<Type, Delegate> _actionByType 
        = new Dictionary<Type, Delegate>();

    public void RegisterProcedure<T>(Action<T> action)
    {
        _actionByType[typeof(T)] = action;
    }

    public void ProcessItem(object item)
    {
        Delegate action;
        if (_actionByType.TryGetValue(item.GetType(), out action))
        {
            // Can this call to DynamicInvoke be avoided?
            action.DynamicInvoke(item);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我在其他地方读到,直接调用委托(带括号)比调用快几个数量级DynamicInvoke,这是有道理的.

对于上面的代码示例,我想知道我是否可以执行类型检查并以某种方式提高性能.

一些上下文:我有一个对象流,可以在各种处理程序中运行,这些处理程序可以在运行时注册/取消注册.上面的模式完全符合我的目的,但如果可能的话,我想让它变得更加快捷.

一种选择是存储Action<object>Dictionary,并Action<T>用另一个委托包装代理.我还没有比较第二次间接调用会影响的性能变化.

.net c# generics delegates dynamic-invoke

11
推荐指数
2
解决办法
6512
查看次数

有没有办法在C#中进行动态隐式类型转换?

给定此类具有隐式转换运算符:

public class MyDateTime
{
    public static implicit operator MyDateTime(System.Int64 encoded)
    {
        return new MyDateTime(encoded);
    }

    public MyDateTime(System.Int64 encoded)
    {
        _encoded = encoded;
    }
    System.Int64 _encoded;
}
Run Code Online (Sandbox Code Playgroud)

我现在可以做以下事情:

long a = 5;
MyDateTime b = a;
Run Code Online (Sandbox Code Playgroud)

但不是以下内容:

long f = 5;
object g = f;
MyDateTime h = g;
Run Code Online (Sandbox Code Playgroud)

这给出了编译时间:

无法将类型'object'隐式转换为'MyDateTime'.

我感觉合理.

现在我修改前面的例子如下:

long f = 5;
object g = f;
MyDateTime h = (MyDateTime)g;
Run Code Online (Sandbox Code Playgroud)

编译好了.现在我得到一个运行时InvalidCastException:

无法将"System.Int64"类型的对象强制转换为"MyDateTime"类型.

这告诉我C#隐式转换运算符仅在编译时应用,并且在.NET运行时试图将对象动态转换为另一种类型时不应用.

我的问题:

  1. 我对么?
  2. 还有其他方法可以做到这一点吗?

顺便说一句,完整的应用程序是我Delegate.DynamicInvoke()用来调用一个带MyDateTime参数的函数,而我传递给的参数的类型很DynamicInvoke长.

c# dynamic-cast type-conversion implicit-cast dynamic-invoke

11
推荐指数
1
解决办法
2949
查看次数

在muticast委托上使用慢速DynamicInvoke的替代方法

我在基类中有以下代码:

public static void InvokeExternal(Delegate d, object param, object sender)
{
    if (d != null)
    {
        //Check each invocation target
        foreach (Delegate dDelgate in d.GetInvocationList())
        {
            if (dDelgate.Target != null && dDelgate.Target is System.ComponentModel.ISynchronizeInvoke
                && ((System.ComponentModel.ISynchronizeInvoke)(dDelgate.Target)).InvokeRequired)
            {
                //If target is ISynchronizeInvoke and Invoke is required, invoke via ISynchronizeInvoke
                ((System.ComponentModel.ISynchronizeInvoke)(dDelgate.Target)).Invoke(dDelgate, new object[] { sender, param });
            }
            else
            {
                //Else invoke dynamically
                dDelgate.DynamicInvoke(sender, param);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

此代码示例负责调用一个事件,表示为多播委托,其中调用目标包括不关心跨线程的小类,以及实现ISynchronizeInvoke和关注跨线程的类,如Windows窗体控件.

理论上,这个片段工作得很好,没有错误发生.但是DynamicInvoke速度非常慢,并不是说它是应用程序的当前瓶颈.

所以,我的问题是:有没有办法加快这个小功能而不破坏功能直接订阅事件?

所有活动/代表的签名是 (object sender, EventArgs param)

c# events delegates invoke dynamic-invoke

4
推荐指数
1
解决办法
5178
查看次数

如何将对象数组作为单独的参数传递给方法?

我有以下代码:

public class MyClass
{
    private Delegate m_action;
    public object[] m_args;

    public MyClass()
    {

    }

    public MyClass(Delegate action, params object[] args)
    {
        m_args = args;
        m_action = action;
    }

    public void Execute()
    {
        m_action.DynamicInvoke(m_args);
    }
}
Run Code Online (Sandbox Code Playgroud)

这种方法的问题在于 m_args 本身就是一个对象,它的内容没有被扁平化为单独的 params 条目。我怎样才能解决这个问题?

.net c# parameters delegates dynamic-invoke

1
推荐指数
1
解决办法
3939
查看次数

快速获取表达式方法调用目标的方法

鉴于以下代码行,

Expression<Action> expression = () => target.ToString();
Run Code Online (Sandbox Code Playgroud)

有没有快速获取target对象的方法?

下面的代码有效

public object GetExpressionTarget<T>(Expression<T> expression)
{
    MethodCallExpression methodCall = (MethodCallExpression) expression.Body;
    LambdaExpression theTarget = Expression.Lambda(methodCall.Object, null);
    Delegate compiled = theTarget.Compile();

    return compiled.DynamicInvoke();    }
Run Code Online (Sandbox Code Playgroud)

但是非常非常慢。


有没有更快的方法来获取方法调用表达式的目标?


对我的代码 ( GetDelegate,DelegateCompileDelegateDynamicInvoke) 以及@IvanStoev 的代码 ( GetFunc,FuncCompileFuncInvoke) 进行基准测试会产生以下结果:

|                Method |           Mean |         Error |        StdDev |
|---------------------- |----------------|---------------|---------------|
|       DelegateCompile | 165,068.477 ns | 2,671.3001 ns | 2,498.7358 ns |
|           FuncCompile …
Run Code Online (Sandbox Code Playgroud)

c# performance delegates expression dynamic-invoke

1
推荐指数
1
解决办法
331
查看次数