Powershell线程处理问题
我遇到了 powershell 问题,也许有人可以帮助我。我正在使用 powershell 2.0,我想创建和使用线程。我知道我可以使用工作,但这不是我想要的。 我想要一个脚本,它创建 Windows 窗体,并运行后台线程。由于表单需要 STA,所以这并不容易。运行“powershell.exe -sta”不是解决方案。
下面是我编写的脚本,用于简单的线程处理。但这不起作用。即使新线程也不会被创建。有什么建议吗,有什么问题吗?如果可以的话请帮助我!
问候,彼得。
function ThreadProc() {
for ($i = 0; $i -lt 10; $i++) {
$ApartmentState = [System.Threading.Thread]::CurrentThread.GetApartmentState()
Write-Host "ThreadProc ($ApartmentState): $i"
# Yield the rest of the time slice.
[System.Threading.Thread]::Sleep(0)
}
}
$ApartmentState = [System.Threading.Thread]::CurrentThread.GetApartmentState()
Write-Host "Main thread ($ApartmentState): Start a second thread."
$thread_job = New-Object System.Threading.ThreadStart(ThreadProc)
$thread = New-Object System.Threading.Thread($thread_job)
$thread.CurrentThread.SetApartmentState([System.Threading.ApartmentState]::STA)
$thread.Start()
for ($i = 0; $i -lt 4; $i++) {
Write-Host("Main thread: Do some work.")
[System.Threading.Thread]::Sleep(0)
}
Write-Host("Main thread: Call Join(), to wait until ThreadProc ends.")
$thread.Join()
Write-Host("Main thread: ThreadProc.Join has returned. Program end.")
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
注意到您的脚本中存在一些错误。首先 $thread_job,尝试这样做:
您需要将 ThreadProc 放在括号中,否则它将被计算而不是作为函数传递。其次,您只需指定 ThreadStart 等委托的类型,PowerShell 就会为您转换内容;不需要新对象。
其次 CurrentThread 是一个静态成员 - 我猜 $thread.CurrentThread 是一个拼写错误,你的意思是:
我想你在让它工作时仍然会遇到问题 - 每当我尝试在 PowerShell 中使用线程之前我总是发生了严重的崩溃,没有真正的解释...
您可以用 C# 编写一个 cmdlet 并调用它吗?这样可能更容易做事 - 您可以设置一个新的运行空间并在另一个运行空间的线程中运行命令。
编辑
找到这些可能对您有帮助的链接:
http://weblogs.asp.net/adweigert/archive/2008/04/29/powershell-threading-for-powershell-v1-0.aspx
http://blogs.msdn.com/b/powershell/archive/2007/03/23/thread-apartmentstate-and-powershell-execution-thread.aspx
Noticed a couple of mistakes in your script. Firstly $thread_job, try this instead:
You need to put the brackets around ThreadProc or it will be evaluated rather than passed as a function. Secondly you can just specify the type for delegates like ThreadStart and PowerShell will convert things for you; no need for New-Object.
Secondly CurrentThread is a static member - I'm guessing $thread.CurrentThread is a typo and you meant:
I imagine you'll still have problems getting it to work though - whenever I've tried using threads in PowerShell before I've always had nasty crashes with no real explanation...
Can you write a cmdlet in C# and call into that instead? Might be easier to do things that way - you could setup a new Runspace and run your command in the other Runspace's thread.
EDIT
Found these links that might help you:
http://weblogs.asp.net/adweigert/archive/2008/04/29/powershell-threading-for-powershell-v1-0.aspx
http://blogs.msdn.com/b/powershell/archive/2007/03/23/thread-apartmentstate-and-powershell-execution-thread.aspx
我认为您的问题接近于名为 Powershell 和后台工作人员的帖子。后台工作人员用于在后台线程。
尽管 Powershell 工作在 .NET 之上,但并不产生中间语言 (IL)。它是一种解释性语言,其代码不能在外部运行
powershell 运行空间的上下文。您也许可以使用您的代码创建我们自己的 PowerShell 运行空间并在那里运行您的脚本,然后编组
结果返回到您的主要会话。
I think that your question is somewhere close to a post called Powershell and Backgroundworker.Background worker is for running .NET code on a background thread.
Powershell, though is working on the top of .NET doesn't produce intermediate language (IL). Its an interpreted language and its code cannot run outside of the
context of a powershell runspace. you perhaps can use your code creating our own PowerShell Runspace and running your script there, and marshall the
results back to your primary session.
这是在 System.Threading.Thread 中播放 ScriptBlock 的有效解决方案。您还可以在 Thread.Start(args[]) 中传递参数并将 param(parameters[]) 添加到 ScriptBlock。在 PowerShell 中还有许多其他方法来获取独立线程,但这是我发现使用原始 [System.Threading.Thread] 的方法;
This is a working solution to plays a ScriptBlock in a System.Threading.Thread. You can also pass arguments in Thread.Start(args[]) and add param(parameters[]) to ScriptBlock. There is many other ways to get independent threads in PowerShell, but this is the way I have founded to use original [System.Threading.Thread];