PowerShell ulega awarii po wywołaniu zdarzenia .NET z parametrem ref
, który subskrybowałem.PowerShell ulega awarii podczas używania parametru ref w zdarzeniu .NET
Sprowadziłem problem do następującego kodu.
NET:
namespace PSEventTest
{
public delegate void BadHandler(ref string str);
public class PSEventTest
{
public event BadHandler BadEvent;
public void InvokeBad()
{
var handler = BadEvent;
if (handler != null)
{
var str = "bad";
handler(ref str);
}
}
}
}
PowerShell:
Add-Type -path $PSScriptRoot"\PSEventTest.dll"
$obj = New-Object PSEventTest.PSEventTest
$bad = Register-ObjectEvent -InputObject $obj -EventName BadEvent -Action {
Write-Host "bad!" # it also crashes if this script-block is empty
}
$obj.InvokeBad(); # crash
kiedy uruchomić skrypt PowerShell uzyskać to:
Jeśli pędzę Debug
i dostać to od Visual Studio:
The copy exception detail to the clipboard
daje mi ten
System.NullReferenceException was unhandled
Message: An unhandled exception of type 'System.NullReferenceException' occurred in Unknown Module.
Additional information: Object reference not set to an instance of an object.
Chyba musiał dostarczyć ciąg do skryptu bloku -Action
jakoś, ale nie wiem jak.
P.S. Używam PowerShell 4:
PS C:\Windows\system32> $PSVersionTable.PSVersion
Major Minor Build Revision
----- ----- ----- --------
4 0 -1 -1
Już debugowałem. Odkryłem, że blok skryptu PowerShell jest "niezsynchronizowany" z kodem .NET. Jeśli zrobię ten sam kod .NET bez "ref", widzę, że blok skryptu zdarzenia nie zostanie wykonany przed zakończeniem wywołania "InvokeBad". Co oznacza, że w przypadku z parametrem 'ref' wykonanie kodu .NET mija punkt, w którym odniesienie może zostać zaktualizowane po wykonaniu bloku skryptu zdarzenia PowerShell. Może to być spowodowane tym, że wywołałem zdarzenie z programu PowerShell? –
Co zwróci '$ HOST.Runspace.ApartmentState'? STA lub MTA? –
@ MathiasR.Jessen '$ HOST.Runspace.ApartmentState' zwraca' STA' zarówno wewnątrz, jak i na zewnątrz zdarzenia blockblock. –