【问题标题】:Invoking a System.Action instance asynchronously in PowerShell在 PowerShell 中异步调用 System.Action 实例
【发布时间】:2013-02-12 20:21:01
【问题描述】:

背景

首先我创建一个System.Action 实例:

PS C:\Users\KnutKristian> $a = [Action]{}

看看成员:

PS C:\Users\KnutKristian> $a | gm

   TypeName: System.Action

Name              MemberType Definition                                        
----              ---------- ----------                                        
BeginInvoke       Method     System.IAsyncResult BeginInvoke(System.AsyncCal...
Clone             Method     System.Object Clone(), System.Object ICloneable...
DynamicInvoke     Method     System.Object DynamicInvoke(Params System.Objec...
EndInvoke         Method     void EndInvoke(System.IAsyncResult result)        
Equals            Method     bool Equals(System.Object obj)                    
GetHashCode       Method     int GetHashCode()                                 
GetInvocationList Method     System.Delegate[] GetInvocationList()             
GetObjectData     Method     void GetObjectData(System.Runtime.Serialization...
GetType           Method     type GetType()                                    
Invoke            Method     void Invoke()                                     
ToString          Method     string ToString()                                 
Method            Property   System.Reflection.MethodInfo Method {get;}        
Target            Property   System.Object Target {get;}

BeginInvoke 签名:

PS C:\Users\KnutKristian> $a.BeginInvoke.OverloadDefinitions
System.IAsyncResult BeginInvoke(System.AsyncCallback callback, System.Object ob
ject)

当我尝试开始调用时,我收到此错误:

PS C:\Users\KnutKristian> $a.BeginInvoke($null, $null)
Exception calling "BeginInvoke" with "2" argument(s): "The object must be a run
time Reflection object."
At line:1 char:1
+ $a.BeginInvoke($null, $null)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentException

指定内容没有帮助:

PS C:\Users\…> $a.BeginInvoke([AsyncCallback]{param([IAsyncResult] $a)}, '')
Exception calling "BeginInvoke" with "2" argument(s): "The object must be a run
time Reflection object."
At line:1 char:1
+ $a.BeginInvoke([AsyncCallback]{param([IAsyncResult] $a)}, '')
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ArgumentException

一些异常信息:

PS C:\Users\KnutKristian> $Error[0].Exception.InnerException | gm


   TypeName: System.ArgumentException

Name             MemberType Definition                                         
----             ---------- ----------                                         
Equals           Method     bool Equals(System.Object obj), bool _Exception....
GetBaseException Method     System.Exception GetBaseException(), System.Exce...
GetHashCode      Method     int GetHashCode(), int _Exception.GetHashCode()    
GetObjectData    Method     void GetObjectData(System.Runtime.Serialization....
GetType          Method     type GetType(), type _Exception.GetType()          
ToString         Method     string ToString(), string _Exception.ToString()    
Data             Property   System.Collections.IDictionary Data {get;}         
HelpLink         Property   string HelpLink {get;set;}                         
HResult          Property   int HResult {get;}                                 
InnerException   Property   System.Exception InnerException {get;}             
Message          Property   string Message {get;}                              
ParamName        Property   string ParamName {get;}                            
Source           Property   string Source {get;set;}                           
StackTrace       Property   string StackTrace {get;}                           
TargetSite       Property   System.Reflection.MethodBase TargetSite {get;}


PS C:\Users\KnutKristian> $Error[0].Exception.InnerException |
    fl Message, ParamName, InnerException -Force


Message        : The object must be a runtime Reflection object.
ParamName      : 
InnerException : 

问题

  1. 消息是什么

    对象必须是运行时反射对象。

    在这种情况下是什么意思?据我所知,这里只有 .NET 对象。也许抱怨一些 PowerShell 的具体细节?

  2. 如何才能成功运行BeginInvoke方法?

【问题讨论】:

  • 尝试创建一个 powershell 对象并为其提供一些属性并传递它而不是 null。来自维基百科“在计算机科学中,反射是计算机程序在运行时检查(参见类型自省)和修改对象的结构和行为(特别是值、元数据、属性和函数)的能力。[1]反射最常用于高级虚拟机编程语言(如 Smalltalk 和脚本语言)以及显式类型或静态类型的编程语言(如 Java、ML、Haskell 和 C#)中。”
  • '' 是一个派生自System.ObjectSystem.String 实例。我试图用New-Object -TypeName PSObject -Property @{ Prop1 = 'val' } 替换''。没区别。问题 1 是特定于上下文的。为什么会出现在这里?对我来说毫无意义。

标签: powershell asynchronous lambda begininvoke


【解决方案1】:

试试下面的代码。

[Action]{}|%{$_.BeginInvoke($null, $null)}


IsCompleted            : True
AsyncDelegate          : System.Action
AsyncState             :
CompletedSynchronously : False
EndInvokeCalled        : False
AsyncWaitHandle        : System.Threading.ManualResetEvent
NextSink               :

请查看以下文章以了解 RunTimeType http://msdn.microsoft.com/en-us/library/ms172329.aspx

【讨论】:

  • 在 Powershell 5 中运行它我得到:使用“2”参数调用“BeginInvoke”的异常:“对象必须是运行时反射对象。”在 line:1 char:21 + $foo = [Action]{}|%{$_.BeginInvoke($null, $null)} + ~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : ArgumentException
【解决方案2】:

要异步运行,您可以尝试jobs(多进程方式,效率不高),或者您可以尝试创建RunspacePool,如this post所示。

【讨论】:

  • 我正在阅读一本关于 .NET 和线程的书。我在 PowerShell 中做示例。探索 .NET 库的绝佳语言。我想在 PowerShell 中运行 BeginInvoke 方法。我不想要替代品。
  • 不确定 PowerShell 是否是测试多线程的好地方。你最好使用 C# 和 VS。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-31
  • 2018-03-14
  • 2011-08-03
  • 2017-03-07
  • 2023-04-04
相关资源
最近更新 更多