问题描述
我需要编写一个Powershell脚本,该脚本从异步读取,然后将其写入System.IO.Ports.SerialPort
对象。但是,在编写代码以使用Start-Job
来简单地从对象中读取代码时,出现了错误。到目前为止,这是我的代码:
$func = {
function CheckPort
{
param (
[parameter(Mandatory=$true,ValueFromPipeline=$true)]
[System.IO.Ports.SerialPort]$port
)
Write-Output $port.ReadLine()
}
}
$port = new-Object System.IO.Ports.SerialPort COM4,9600,None,8,one
$port.open()
Start-Job -ScriptBlock {CheckPort $args[0]} -ArgumentList $port -Name “$computerName” -InitializationScript $func
运行上面的代码时,使用Receive-Object
检查子流程的输出后,我看到一个错误。似乎不是$port
对象按原样传递,而是先序列化然后未序列化:
Error: "Cannot convert the "System.IO.Ports.SerialPort" value of type "Deserialized.System.IO.Ports.SerialPort" to type "System.IO.Ports.SerialPort"."
+ CategoryInfo : InvalidData: (:) [CheckPort],ParameterBindin...mationException
+ FullyQualifiedErrorId : ParameterargumentTransformationError,CheckPort
+ PSComputerName : localhost
反正有使用Start-Job
通过引用传递自变量吗? $port.ReadLine()
正在阻塞,没有其他方法可以仅检查是否有要读取的内容,并且我有时需要写入端口,因此在这里肯定需要异步执行。
如果我尝试$using
,也会遇到相同的错误:
$port = new-Object System.IO.Ports.SerialPort COM4,one
$port.open()
Start-Job -ScriptBlock {
$myPort = $using:port
Write-Output $myPort.ReadLine()
}
解决方法
这两个方法不序列化对象。 foreach-object -parallel
需要PS 7,但可以在PS 5中下载start-threadjob。
Start-ThreadJob {
$myPort = $using:port
$myPort.ReadLine()
} | receive-job -wait -auto
foreach-object -parallel {
$myPort = $using:port
$myPort.ReadLine()
}