gpt4 book ai didi

.net - 对 Control.Invoke() 的实现感到好奇

转载 作者:行者123 更新时间:2023-12-03 19:34:46 26 4
gpt4 key购买 nike

Control.Invoke(Delegate) 究竟做了什么来让委托(delegate)在 GUI 线程上运行?此外,我的理解是调用将阻塞,直到调用的函数完成。它是如何做到这一点的?

我想要一些好的坚韧不拔的细节。我希望能学到一些有趣的东西。

最佳答案

编辑:控件实现 ISynchronizeInvoke界面,您可以使用 SynchronizationContext 做出相同的效果并调用Post当您调用 Invoke .就像是:

public object Invoke(Delegate method, object[] args)
{
if (method == null)
{
throw new ArgumentNullException("method");
}

object objectToGet = null;

SendOrPostCallback invoker = new SendOrPostCallback(
delegate(object data)
{
objectToGet = method.DynamicInvoke(args);
});

_currentContext.Send(new SendOrPostCallback(invoker), method.Target);

return objectToGet;
}

使用 Reflector 的进一步调查表明 Invoke使用一些 native API 调用来实现:
private object MarshaledInvoke(Control caller, Delegate method, object[] args, bool synchronous)
{
int num;
if (!this.IsHandleCreated)
{
throw new InvalidOperationException(SR.GetString("ErrorNoMarshalingThread"));
}
if (((ActiveXImpl) this.Properties.GetObject(PropActiveXImpl)) != null)
{
IntSecurity.UnmanagedCode.Demand();
}
bool flag = false;
if ((SafeNativeMethods.GetWindowThreadProcessId(new HandleRef(this, this.Handle), out num) == SafeNativeMethods.GetCurrentThreadId()) && synchronous)
{
flag = true;
}
ExecutionContext executionContext = null;
if (!flag)
{
executionContext = ExecutionContext.Capture();
}
ThreadMethodEntry entry = new ThreadMethodEntry(caller, this, method, args, synchronous, executionContext);
lock (this)
{
if (this.threadCallbackList == null)
{
this.threadCallbackList = new Queue();
}
}
lock (this.threadCallbackList)
{
if (threadCallbackMessage == 0)
{
threadCallbackMessage = SafeNativeMethods.RegisterWindowMessage(Application.WindowMessagesVersion + "_ThreadCallbackMessage");
}
this.threadCallbackList.Enqueue(entry);
}
if (flag)
{
this.InvokeMarshaledCallbacks();
}
else
{
UnsafeNativeMethods.PostMessage(new HandleRef(this, this.Handle), threadCallbackMessage, IntPtr.Zero, IntPtr.Zero);
}
if (!synchronous)
{
return entry;
}
if (!entry.IsCompleted)
{
this.WaitForWaitHandle(entry.AsyncWaitHandle);
}
if (entry.exception != null)
{
throw entry.exception;
}
return entry.retVal;
}

关于.net - 对 Control.Invoke() 的实现感到好奇,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6948643/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com