[英]Can't write to console in async C# code when called from powershell ISE
I have a PowerShell script that needs to call C# to do work, some of it asynchronously. 我有一个PowerShell脚本,需要调用C#才能工作,其中一些异步地进行。 While debugging some errors that only occur when the C# code is called from PowerShell, I noticed something I wasn't expecting.
调试仅在从PowerShell调用C#代码时会发生的一些错误时,我注意到了一些意料之外的事情。 In the C# code, if I made a call to
Console.WriteLine
it wrote to the PowerShell console as expected unless I was using PowerShell ISE and it was called after I did an await in an async function. 在C#代码中,如果我调用
Console.WriteLine
它将按预期方式写入PowerShell控制台, 除非我使用PowerShell ISE,并且在异步函数中等待后调用了它。
Here's a sample script that shows the issue: 这是显示问题的示例脚本:
$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()
In here, I'm just calling an asynchronous function, waiting for it to complete, and returning the result. 在这里,我只是调用一个异步函数,等待它完成,然后返回结果。 Inside the function, I just try to log before and after putting a thread to sleep for a few seconds before returning a value so that I know that the function fully executed.
在函数内部,我只是尝试在使线程休眠几秒钟之前和之后记录日志,然后返回值,以便我知道该函数已完全执行。
I would expect to see: 我希望看到:
Before await
After await
2
And that's what I see when running as a C# console application or in basic PowerShell, but when running through PowerShell ISE, I see: 这就是我作为C#控制台应用程序或在基本PowerShell中运行时所看到的,但是通过PowerShell ISE运行时,我看到了:
Before await
2
Can anyone explain why that would be? 谁能解释为什么会这样?
PowerShell ISE use Console.SetOut
with HostTextWriter
to capture and print Console.WriteLine
output on PowerShell ISE host window. PowerShell ISE与
HostTextWriter
一起使用Console.SetOut
来捕获和打印PowerShell ISE主机窗口上的Console.WriteLine
输出。 And HostTextWriter
redirect Console.WriteLine
to PowerShell host only if host registered ( HostTextWriter.RegisterHost
) for current thread. 并且只有在为当前线程注册了主机(
HostTextWriter.RegisterHost
)的情况下, HostTextWriter
将Console.WriteLine
重定向到PowerShell主机。
In absence of SynchronizationContext
continuation caused by await
keyword will be executed in arbitrary thread pool thread, which likely does not have any registered PowerShell host to redirect Console.WriteLine
to. 在缺少
SynchronizationContext
情况下,将在任意线程池线程中执行由await
关键字引起的延续,该线程池可能没有任何注册的PowerShell主机将Console.WriteLine
重定向到。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.