class Program
{
public delegate void AAA();
static void Main(string[] args)
{
AAA a = new AAA(Test);
a.BeginInvoke(new AsyncCallback(CallBack), null);
}
private static void Test() { }
private static void CallBack(IAsyncResult ia)
{ }
}
代码不用说了,a.BeginInvoke(new AsyncCallback(CallBack), null);想看看BeginInvoke内部是怎么写的,可是怎么也找不到“此BeginInvoke” 在MSDN上搜BeginInvoke方法,显示的几乎全是Control类及其子类上的BeginInvoke。既然“此BeginInvoke”是实例a调用出来的,那么我就去Delegate类里找也是找不到。很郁闷大家知道这个方法到底属于哪个类吗
System.Runtime.Remoting.Proxies.RemotingProxy : RealProxy, IRemotingTypeInfo BeginInvoke & EndInvoke都是调用InternalInvoke 方法
public virtual IAsyncResult BeginInvoke(AsyncCallback callback, object @object);编译你的代码,用reflector看AAA,
[MethodImpl(0, MethodCodeType=MethodCodeType.Runtime)]是运行时的操作。。无法继续看了。
有??我在MSDN上怎么没有看到?
我用的是08的MSDN,System.Runtime.Remoting.Proxies.RemotingProxy这个类没有找到。。RealProxy这个倒是找到了
[SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
public IAsyncResult BeginInvoke(Delegate method, params Object[] args) {
using (new MultithreadSafeCallScope()) {
Control marshaler = FindMarshalingControl();
return(IAsyncResult)marshaler.MarshaledInvoke(this, method, args, false);
}
} private Control FindMarshalingControl() {
//
lock(this) {
Control c = this; while (c != null && !c.IsHandleCreated) {
Control p = c.ParentInternal;
c = p;
}
if (c == null) {
// No control with a created handle. We
// just use our own control. MarshaledInvoke
// will throw an exception because there
// is no handle.
//
c = this;
}
else {
Debug.Assert(c.IsHandleCreated, "FindMarshalingControl chose a bad control.");
} return(Control)c;
}
} private Object MarshaledInvoke(Control caller, Delegate method, Object[] args, bool synchronous) { // Marshaling an invoke occurs in three steps:
//
// 1. Create a ThreadMethodEntry that contains the packet of information
// about this invoke. This TME is placed on a linked list of entries because
// we have a gap between the time we PostMessage and the time it actually
// gets processed, and this gap may allow other invokes to come in. Access
// to this linked list is always synchronized.
//
// 2. Post ourselves a message. Our caller has already determined the
// best control to call us on, and we should almost always have a handle.
//
// 3. If we're synchronous, wait for the message to get processed. We don't do
// a SendMessage here so we're compatible with OLE, which will abort many
// types of calls if we're within a SendMessage.
// if (!IsHandleCreated) {
throw new InvalidOperationException(SR.GetString(SR.ErrorNoMarshalingThread));
} // We have to demand unmanaged code permission here for the control hosted in
// the browser case. Without this check, we will expose a security hole, because
// ActiveXImpl.OnMessage() will assert unmanaged code for everyone as part of
// its implementation.
// The right fix is to remove the Assert() on top of the ActiveXImpl class, and
// visit each method to see if it needs unmanaged code permission, and if so, add
// the permission just to that method(s).
//
ActiveXImpl activeXImpl = (ActiveXImpl)Properties.GetObject(PropActiveXImpl);
if (activeXImpl != null) {
IntSecurity.UnmanagedCode.Demand();
}
// We don't want to wait if we're on the same thread, or else we'll deadlock.
// It is important that syncSameThread always be false for asynchronous calls.
//
bool syncSameThread = false;
int pid; // ignored
if (SafeNativeMethods.GetWindowThreadProcessId(new HandleRef(this, Handle), out pid) == SafeNativeMethods.GetCurrentThreadId()) {
if (synchronous)
syncSameThread = true;
} // Store the compressed stack information from the thread that is calling the Invoke()
// so we can assign the same security context to the thread that will actually execute
// the delegate being passed.
//
ExecutionContext executionContext = null;
if (!syncSameThread) {
executionContext = ExecutionContext.Capture();
}
ThreadMethodEntry tme = new ThreadMethodEntry(caller, method, args, synchronous, executionContext);
lock (this) {
if (threadCallbackList == null) {
threadCallbackList = new Queue();
}
}
lock (threadCallbackList) {
if (threadCallbackMessage == 0) {
threadCallbackMessage = SafeNativeMethods.RegisterWindowMessage(Application.WindowMessagesVersion + "_ThreadCallbackMessage");
}
threadCallbackList.Enqueue(tme);
}
if (syncSameThread) {
InvokeMarshaledCallbacks();
} else {
//
UnsafeNativeMethods.PostMessage(new HandleRef(this, Handle), threadCallbackMessage, IntPtr.Zero, IntPtr.Zero);
} if (synchronous) {
if (!tme.IsCompleted) {
WaitForWaitHandle(tme.AsyncWaitHandle);
}
if (tme.exception != null) {
throw tme.exception;
}
return tme.retVal;
}
else {
return(IAsyncResult)tme;
}
}
确切的说是 msdn 中看不到。.net 是开源的 ,接下来怎么做 你应该知道了
public class AAA : System.MulticastDelegate
所以委托就是一个类,继承自MulticastDelegate
可以用ildasm.exe打开你的EXE文件看看IL代码就更清楚了
使用vs只能提示的时候。
放到一个方法上面,
会提示如 Delegate类的ToString()方法
string object.ToString()
为什么是object不是Delegate呢?
因为这里显示的就是方法定义的地方了!所以你会发现,
AAA委托的时候,
方法定义显示的是:
AAA.XXX
所以,方法应该定义在AAA中。不过你也没写,是C#编译器帮你写了。
这一类的都是运行时加入的,
.net中有一些最终运行的机器码是在运行时产生,加入,执行的。
你说的是用reflector看吧?我是用这个看呢,主要是,我不知道我找不到入口,可以理解吗?我不知道最上层的那个调用在哪我问你怎么看到的,是想问你你的入口是哪
用IL的确可以看到它继承自MulticastDelegate,MSDN上也有相应说明。但是!BeginInvoke方法呢?