谁能告诉我为什么这段代码的行为方式呢?查看代码中嵌入的评论......
我错过了一些非常明显的东西吗?
using System;
namespace ConsoleApplication3
{
public class Program
{
static void Main(string[] args)
{
var c = new MyChild();
c.X();
Console.ReadLine();
}
}
public class MyParent
{
public virtual void X()
{
Console.WriteLine("Executing MyParent");
}
}
delegate void MyDelegate();
public class MyChild : MyParent
{
public override void X()
{
Console.WriteLine("Executing MyChild");
MyDelegate md = base.X;
// The following two calls look like they should behave the same,
// but they behave differently!
// Why does Invoke() call …Run Code Online (Sandbox Code Playgroud) 我想调用具有某个属性的方法.所以我循环遍历所有程序集和所有方法以使用我的属性查找方法.工作正常,但是当我得到它的MethodInfo时,如何调用某个方法.
AppDomain app = AppDomain.CurrentDomain;
Assembly[] ass = app.GetAssemblies();
Type[] types;
foreach (Assembly a in ass)
{
types = a.GetTypes();
foreach (Type t in types)
{
MethodInfo[] methods = t.GetMethods();
foreach (MethodInfo method in methods)
{
// Invoke a certain method
}
}
}
Run Code Online (Sandbox Code Playgroud)
问题是我不知道包含该特定方法的类的实例.所以我无法正确调用它,因为这些方法不是静态的.我还想避免在可能的情况下创建此类的新实例.
我有一个主UI线程,它运行应用程序并创建主窗口表单(让我们称之为W).我还有一个辅助线程,我旋转并创建一个对话框(让我们称之为B).
我想将对话框的所有者设置B为主窗口W.Bs所有者的设置发生在创建的线程上B.基本上:
b.Owner = w;
Run Code Online (Sandbox Code Playgroud)
但这会引发一个跨线程异常,告诉我我正在尝试W从错误的线程访问该对象.
于是,我就用主UI线程上执行代码,Control.Invoke上W.但是,我得到同样的错误,告诉我我正在尝试B从错误的线程访问:
System.InvalidOperationException was unhandled by user code
Message=Cross-thread operation not valid: Control 'B' accessed from a
thread other than the thread it was created on.
Source=System.Windows.Forms
Run Code Online (Sandbox Code Playgroud)
我该怎么做呢?
Control.Invoke(Delegate)究竟做了什么来让代理在GUI线程上运行?此外,我的理解是invoke将阻塞,直到被调用的函数完成.它是如何实现这一目标的?
我想要一些好的细节.我希望学到一些有趣的东西.
我无法从本地计算机访问Powershell远程会话中的服务器上的UNC路径.我可以直接在Servers Cmd提示符中使用它们.
实际上,我已登录到服务器并将UNC路径映射为本地驱动器(例如X :).使用登录时重新连接选项.
我有一个批处理文件驻留在这个X:驱动器中,我想使用本地脚本中的invoke命令远程运行它.但是,它失败了.
它说"找不到驱动器.名称为X的驱动器不存在".
此外,当我尝试使用scriptblock中的net use命令映射驱动器时,它也会抛出错误 - 系统错误1223 - 本机命令错误.
我使用管理员凭据登录此服务器.
任何人都可以请帮助我,我想要做的就是远程运行脚本驻留在这个UNC路径?
此外,当我将服务器中的UNC路径映射为本地驱动器时,为什么我无法在PS远程会话中使用它?
提前致谢.TS
我有以下方法签名:
public static void InvokeInFuture(Delegate method, params object[] args)
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
委托和参数将保存到集合中以供将来调用.
有没有办法可以检查arguments数组是否满足委托要求而不调用它?
谢谢.
编辑: 感谢您的反思实现,但我正在寻找一种内置的方法来实现这一点.我不想重新转换方向盘,.NET Framework已经在Delegate.DynamicInvoke()的某个地方实现了这种检查,实现处理所有那些只有微软开发人员可以考虑的疯狂特殊情况,并通过了单元测试和QA.有没有办法使用这个内置实现?
谢谢.
我一直在用__invoke魔术方法做一些测试(替换旧代码),我不确定这是不是一个bug:
让我们假设我们有一个班级:
class Calc {
function __invoke($a,$b){
return $a*$b;
}
}
Run Code Online (Sandbox Code Playgroud)
以下是可能的,并且没有任何问题:
$c = new Calc;
$k = $c;
echo $k(4,5); //outputs 20
Run Code Online (Sandbox Code Playgroud)
但是,如果我想要另一个类来存储该对象的实例,这不起作用:
class Test {
public $k;
function __construct() {
$c = new Calc;
$this->k = $c; //Just to show a similar situation than before
// $this-k = new Calc; produces the same error.
}
}
Run Code Online (Sandbox Code Playgroud)
当我们尝试调用它时会发生错误:
$t = new Test;
echo $t->k(4,5); //Error: Call to undefined method Test::k()
Run Code Online (Sandbox Code Playgroud)
我知道"解决方案"可能是在类Test(名为k)中使用call_user_func_array来"转发"调用,但这并不优雅.
我需要将该实例保留在公共类中(出于设计目的)并能够将其作为函数从其他类中调用...任何建议?
更新:
我找到了一些有趣的东西(至少对我而言):
如果我们将"类变量"分配给局部变量,它可以工作:
$t = new Test; …Run Code Online (Sandbox Code Playgroud) 我最近更改了我的应用程序,使用自定义SplashScreen(它只是一个带有Timer的表单,主窗体并自行关闭)到应用程序框架.
这是我做的:
这完全符合我的要求.SplashScreen首先显示,而不是启动事件触发并且它是否正常工作.SplashScreen关闭,显示实际的主窗体.
到现在为止还挺好.但我们的客户有时会在启动期间遇到这个令人讨厌的异常:
System.InvalidOperationException: Invoke oder BeginInvoke kann für ein Steuerelement erst aufgerufen werden, wenn das Fensterhandle erstellt wurde.
bei System.Windows.Forms.Control.WaitForWaitHandle(WaitHandle waitHandle)
bei System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous)
bei System.Windows.Forms.Control.Invoke(Delegate method, Object[] args)
bei System.Windows.Forms.Control.Invoke(Delegate method)
bei Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.HideSplashScreen()
bei Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.MainFormLoadingDone(Object sender, EventArgs e)
bei System.EventHandler.Invoke(Object sender, EventArgs e)
bei System.Windows.Forms.Form.OnLoad(EventArgs e)
bei System.Windows.Forms.Form.OnCreateControl()
bei System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
bei System.Windows.Forms.Control.CreateControl()
bei System.Windows.Forms.Control.WmShowWindow(Message& m)
bei System.Windows.Forms.Control.WndProc(Message& m)
bei System.Windows.Forms.ScrollableControl.WndProc(Message& m)
bei …Run Code Online (Sandbox Code Playgroud) 我正在尝试构建一个使用System.ComponentModel.ISynchronizeInvoke的对象,该对象具有以下方法:(其中包括)
public object Invoke(Delegate method, object[] args)
Run Code Online (Sandbox Code Playgroud)
使用给定参数调用方法的最佳方法是什么?我可以用:
public object Invoke(Delegate method, object[] args)
{
return method.DynamicInvoke(args);
}
Run Code Online (Sandbox Code Playgroud)
但这是后期限制.我的直觉是,这是调用方法的唯一方法..任何想法?
我是线程世界的新手,但我正在研究的应用程序的一些方面要求我使用BackgroundWorker控件来防止UI在执行某些文件操作时冻结.
我要做的是从BackgroundWorker中更新几个表单标签.从来没有使用过这个之前我很快发现我无法访问未在同一个线程中创建的控件,因此经过一些研究后我实现了以下代码,似乎可以使一切工作:
Private Delegate Sub DelegateUpdateStatus(ByVal statusText As String, ByRef currentFile As String)
Private Sub UpdateStatus(ByVal statusText As String, ByVal currentFile As String)
If InvokeRequired Then
Invoke(Sub() LblStatus.Text = statusText)
Invoke(Sub() LblCurrentFile.Text = currentFile)
Else
LblStatus.Text = statusText
LblCurrentFile.Text = currentFile
End If
End Sub
Run Code Online (Sandbox Code Playgroud)
但事情是,我不知道这个代码在做什么,或者为什么需要它.
我做了一些研究,但我没有做过任何真正的工作,我读过的大多数文章都假设了一些先验知识.
我希望了解的三个主要内容:
如上所述,线程仍然是一个非常外国的概念,所以任何简单的英语答案都会非常有用 - 谢谢!
编辑:感谢大家到目前为止的回复.我已经做了一些进一步的阅读,我想知道我是否正确地采用了这种方式.我使用BackgroundWorker的原因是为了确保在我执行文件操作时UI保持响应.问题是,我仍然需要等到BackgroundWorker完成它的工作,所以我可以返回一个指示操作成功的布尔值.有办法解决这个问题,但是从我的阅读中,不得不等待BackgroundWorker完成它的工作就是首先要破坏使用它的目的.那么,阻止UI锁定的最佳方法是什么?
invoke ×10
c# ×4
delegates ×4
winforms ×3
.net ×2
vb.net ×2
arguments ×1
begininvoke ×1
late-binding ×1
mapping ×1
methodinfo ×1
methods ×1
overriding ×1
php ×1
powershell ×1
reflection ×1
remoting ×1
virtual ×1