代表们如何在c#后台工作以及如何有效地使用它们?编辑:我知道他们如何在表面上工作(他们基本上是函数指针,并允许使用他们的地址调用某些签名的回调方法)。我需要知道的是CLR如何在内部实现它们。定义委托时以及何时使用委托对象调用回调方法时幕后会发生什么?代表如何工作(在后台)?
回答
问题的第一部分相对比较简单:代表存储函数指针列表。如果您调用委托,它将调用该内部列表中的所有函数指针。添加和删除接收器(通过Delegate.Combine
和Delegate.Remove
)相当于添加到该列表和从列表中删除。
有关更多底层信息,请参阅ECMA-335(CLI标准),第II.14.5节(方法指针)和II.14.6(代表)。特别要注意的是,委托由一个实例指针(类型为System.Object
)和一个方法指针(类型为System.IntPtr
)组成。方法指针可以通过ldftn
或ldvirtftn
(用于虚拟函数调用)指令获得(在CIL中)。
这两条信息标识任何方法。
它们如何有效使用?
你是什么意思?你知道事件还是你的问题更专业?
重效率 - 目前尚不清楚你的意思,但可以用达到的效率,避免昂贵的反射。例如,通过使用Delegate.CreateDelegate
来创建(键入)预先检查的动态/查找方法委托,而不是使用(较慢)MethodInfo.Invoke
。
一个简单的例子(访问一个类型的静态T Parse(string)
模式),见下文。请注意,它只使用反射一次(每种类型),而不是很多次。这应该在性能反射或典型TypeConverter
用法:
using System;
using System.Reflection;
static class Program { // formatted for space
static void Main() {
// do this in a loop to see benefit...
int i = Test<int>.Parse("123");
float f = Test<float>.Parse("123.45");
}
}
static class Test<T> {
public static T Parse(string text) { return parse(text); }
static readonly Func<string, T> parse;
static Test() {
try {
MethodInfo method = typeof(T).GetMethod("Parse",
BindingFlags.Public | BindingFlags.Static,
null, new Type[] { typeof(string) }, null);
parse = (Func<string, T>) Delegate.CreateDelegate(
typeof(Func<string, T>), method);
} catch (Exception ex) {
string msg = ex.Message;
parse = delegate { throw new NotSupportedException(msg); };
}
}
}
代表在C#是方法指针的列表。即它们存储对代码的引用,并且可以通过指针调用这些方法。这在很多情况下很有用。常见的例子是代理用来实现发布者/订阅者模式的事件处理程序。
当你创建一个委托时,C#编译器会生成一个完整的类。 这个类包含了一个函数引用列表,正如Konrad所说的。 关于委托的好处是它们为您提供了简单的方法,以通知回调异步执行任务。这意味着您可以在后台操作完成时收到通知。 线程池不提供此功能。 代表是一个广泛的话题,我发现杰夫里希特(通过C#的CLR)和Albahari(C#3)书籍提供了特别的帮助。
C#委托是封装对象和方法指针的引用的对象(检查System.Delegate类)。 它们也可以具有对象的空引用来表示对静态方法的调用。
使用参数调用委托时,委托会使用指定的参数调用引用对象上的引用方法。
编译的委托Invoke方法是直接由运行时处理(如用反射可见):
[MethodImpl(0, MethodCodeType=MethodCodeType.Runtime)]
public virtual void Invoke(T obj);
运行时使用所有信息internaly编译一个标准方法调用来引用方法。
当你定义委托
internal delegate void Feedback(Int32 value);
编译器实际上定义了一个完整的类,看起来像这样的东西 :
internal class Feedback : System.MulticastDelegate {
// Constructor
public Feedback(Object object, IntPtr method);
// Method with same prototype as specified by the source code
public virtual void Invoke(Int32 value);
// Methods allowing the callback to be called asynchronously
public virtual IAsyncResult BeginInvoke(Int32 value, AsyncCallback callback, Object object);
public virtual void EndInvoke(IAsyncResult result);
}
来源:Jeffrey Richter - CLR via C#,第17章
- 1. 代码不能在后台工作
- 2. 在后台工作
- 3. DataMan iPhone App如何在后台工作
- 4. 后台bean作用域如何工作?
- 5. 后台工作
- 6. 后台工作
- 7. onBroadcastReceiver在后台工作吗?
- 8. NSTimer在后台工作
- 9. WriteableBitmap的在后台工作
- 10. 后台工作,如何构建命令
- 11. 如何让我的控制台C++程序在后台工作?
- 12. Excel宏:在后台打开工作表并在后台执行分析工作表
- 13. 如何在MySQL工作台
- 14. c#opennetCF后台工作器在100次迭代后停止
- 15. 确保后台工作者正在工作并正在工作
- 16. 如何让NSTimer和一些操作继续在后台工作?
- 17. 如何从后台工作的每个状态的表单
- 18. 什么是延迟后台工作?它是如何工作的?
- 19. 如何在web角色(IIS)中完成后台工作(如工作者角色)?
- 20. 后台工作问题
- 21. 后台工作线程
- 22. C# - 后台工作人员?
- 23. C#,后台工作者类
- 24. C#后台工作问题
- 25. 片段后台工作android
- 26. ASP.NET后台工作线程
- 27. C#取消后台工作
- 28. 后台工作人员
- 29. C#,后台工作人员
- 30. C#后台工作人员
真的吗?他们存储指针?我的印象是事件的确如此,而且代表们有点像强类型的函数类型。 (但我可能会把事情弄混淆。) – scraimer 2009-02-09 09:17:41