System.Threading.Timer убивает консоль PowerShell - PullRequest
0 голосов
/ 15 декабря 2018

Когда я запускаю это в консоли PowerShell:

$callback = [System.Threading.TimerCallback]{
    param($state)
}

$timer = [System.Threading.Timer]::new($callback, $null,
    [timespan]::Zero,
    [timespan]::FromSeconds(1))

Затем, как только вызывается $callback (я убедился, что это является основной причиной, изменив параметр конструктора dueTime от [timespan]::Zero до более длительных задержек), весь консольный процесс падает, говоря, что powershell has stopped working.

В чем может быть причина?как я могу преодолеть это?

1 Ответ

0 голосов
/ 15 декабря 2018

Ошибка:

Нет доступного пространства для выполнения скриптов в этой теме.Вы можете указать его в свойстве DefaultRunspace типа System.Management.Automation.Runspaces.Runspace.

И вытекает из

System.Management.Automation.ScriptBlock.GetContextFromTLS()

Делегат является проблемой.Вот как у меня это работает:

$helper = @'
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Management.Automation.Runspaces;

public class RunspacedDelegateFactory
{
    public static Delegate NewRunspacedDelegate(Delegate _delegate, Runspace runspace)
    {
        Action setRunspace = () => Runspace.DefaultRunspace = runspace;

        return ConcatActionToDelegate(setRunspace, _delegate);
    }

    private static Expression ExpressionInvoke(Delegate _delegate, params Expression[] arguments)
    {
        var invokeMethod = _delegate.GetType().GetMethod("Invoke");

        return Expression.Call(Expression.Constant(_delegate), invokeMethod, arguments);
    }

    public static Delegate ConcatActionToDelegate(Action a, Delegate d)
    {
        var parameters =
            d.GetType().GetMethod("Invoke").GetParameters()
            .Select(p => Expression.Parameter(p.ParameterType, p.Name))
            .ToArray();

        Expression body = Expression.Block(ExpressionInvoke(a), ExpressionInvoke(d, parameters));

        var lambda = Expression.Lambda(d.GetType(), body, parameters);

        var compiled = lambda.Compile();

        return compiled;
    }
}
'@

add-type -TypeDefinition $helper

$runspacedDelegate = [RunspacedDelegateFactory]::NewRunspacedDelegate($callback, [Runspace]::DefaultRunspace)

$timer = [System.Threading.Timer]::new(
    $runspacedDelegate,
    $null,
    [timespan]::Zero,
    [timespan]::FromSeconds(1))

Я позаимствовал NewRunspacedDelegate у

https://www.powershellgallery.com/packages/ContainerTools/0.0.1

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...