从PowerShell ISE调用时,无法在异步C#代码中写入控制台

AJ *_*tis 2 .net c# powershell asynchronous

我有一个PowerShell脚本需要调用C#才能正常工作,其中一些是异步的.在调试一些仅在从PowerShell调用C#代码时出现的错误时,我注意到了一些我没想到的东西.在C#代码中,如果我调用Console.WriteLine它,则按预期写入PowerShell控制台,除非我使用的是PowerShell ISE,并且在我在异步函数中进行等待后调用它.

这是一个显示问题的示例脚本:

$source = @"
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

public class TestClass
{   
    public static int TestWrapper()
    {
        var task = TestAsync();
        task.Wait();
        return task.Result;
    }

    private static async Task<int> TestAsync()
    {
        Console.WriteLine("Before await");
        await Task.Run(() => { Thread.Sleep(2000); return; });
        Console.WriteLine("After await");
        return 2;
    }
}

"@

Add-Type -TypeDefinition $source
[TestClass]::TestWrapper()
Run Code Online (Sandbox Code Playgroud)

在这里,我只是调用异步函数,等待它完成,并返回结果.在函数内部,我只是在返回一个值之前和之后尝试在线程休眠之前和之后进行记录,以便我知道该函数已完全执行.

我希望看到:

Before await
After await
2
Run Code Online (Sandbox Code Playgroud)

这就是我作为C#控制台应用程序或基本PowerShell运行时所看到的,但是当通过PowerShell ISE运行时,我看到:

Before await
2
Run Code Online (Sandbox Code Playgroud)

任何人都可以解释为什么会这样吗?

use*_*407 6

PowerShell ISE中使用Console.SetOutHostTextWriter捕获和打印Console.WriteLine上的PowerShell ISE主机窗口输出.并HostTextWriter重定向Console.WriteLine到只有在主机上注册(PowerShell主机HostTextWriter.RegisterHost)为当前线程.

在没有SynchronizationContextawait关键字引起的延续时,将在任意线程池线程中执行,这可能没有任何已注册的PowerShell主机重定向Console.WriteLine到.