Powershell线程处理问题

时间:2011-09-09 06:29:11

标签: powershell powershell-v2.0

我有一个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.")

2 个答案:

答案 0 :(得分:4)

注意到脚本中的一些错误。首先是$ thread_job,试试这个:

[System.Threading.ThreadStart]$thread_job = {ThreadProc};

您需要将括号放在ThreadProc周围,否则它将被评估而不是作为函数传递。其次,您可以为ThreadStart指定代理类型,PowerShell将为您转换内容;不需要New-Object。

其次,CurrentThread是一个静态成员 - 我猜是$ thread.CurrentThread是一个错字,你的意思是:

$thread.SetApartmentState([System.Threading.ApartmentState]::STA);

我想你在使用它时仍然会遇到问题 - 每当我尝试在PowerShell中使用线程之前,我总是遇到令人讨厌的崩溃但没有真正的解释......

你能用C#写一个cmdlet并调用它吗?可能更容易做到这一点 - 你可以设置一个新的Runspace并在另一个Runspace的线程中运行你的命令。

修改

找到可能对您有帮助的链接:

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

答案 1 :(得分:1)

我认为你的问题是在一个名为Powershell and Backgroundworker的帖子附近。后台工作者是在后台线程上运行.NET代码。

Powershell虽然在.NET的顶层工作但不会产生中间语言(IL)。它是一种解释性语言,它的代码不能在外面运行 powershell运行空间的上下文。你也许可以使用你的代码创建我们自己的PowerShell Runspace并在那里运行你的脚本,然后编写 结果回到您的主要会话。