在Windows 8.1上使用task.run安装Chocolatey文件的问题

时间:2019-01-07 21:22:23

标签: c# .net task windows-8.1 chocolatey

我的任务是创建一个工具,以帮助轻松地建立客户系统。我创建了一个函数,该函数在C#中通过powershell调用巧克力脚本,并使用Task.run创建一个新线程,因此它不会影响UI线程,系统工作正常,但某些计算机出现问题。我无权访问这些计算机并且对他们的系统了解不多,并且由于时间限制而无法访问这些计算机也无济于事。我知道他们有Windows 8.1。给了我Windows 10虚拟机进行测试(我仍然不明白,因为这是Windows 8问题)

这是代码。 我知道一个事实(由于一次访问这些计算机),它停止在Task.Run(()=> task)

有人知道Windows 8.1上的Chocolatey或Tasks是否有问题?

Task callTask = Task.Run(() => ExecuteAsynchronouslyAsync("chocolatey string", CheckBox box, string logName));

public async Task<PowerShellAction> ExecuteAsynchronouslyAsync(String commandStr, CheckBox box, string logName)
{
    powerShellAction = new PowerShellAction();
    powerShellAction.isFinished = false;
    using (PowerShell ps = PowerShell.Create())
    {
        ps.AddScript(commandStr); // adding the script to the powershell script.
        outputCollection = new PSDataCollection<PSObject>();
        outputCollection.DataAdded += OutputData;
        IAsyncResult result = ps.BeginInvoke<PSObject, PSObject>(null, outputCollection);
        PSDataCollection<PSObject> execRes = await Task.Factory.FromAsync(result, ps.EndInvoke);
    }
    return powerShellAction;
}

现在正在尝试获得8.1版的虚拟机以继续尝试调试自己。任何其他建议都将受到欢迎。

1 个答案:

答案 0 :(得分:1)

很遗憾,我不能确保我的建议是正确的。主要原因是,我无法弄清楚PowerShellAction应该是什么。我在这里假设PowerShellSystem.Management.Automation.PowerShell

我建议一些事情:

  1. 由于以下几个原因,您的代码无法编译:您的方法的第一行没有var或类型声明,并且由于添加了string关键字,因此无法进行方法调用。请尝试避免将来再粘贴类似您的代码,因为重建示例非常困难。
  2. 不要将UI控件绕过异步方法,而应使用所需的值(例如,box.IsChecked作为bool)。
  3. 在您的ConfigureAwait(false)中添加await,以防止.NET尝试同步回上下文。
  4. 更加注意方法的异常处理。
  5. 如果您的方法不需要它,则不返回任何内容。

代码(unestet)可能是这样的:

var task = Task.Run(() => ExecutePowerShellAsync("chocolatey string", box.IsChecked, "NameOfTheLog"));

public async Task<PowerShellAction> ExecutePowerShellAsync(String commandStr, bool checkBoxValue, string logName)
{
    var powerShellAction = new PowerShellAction();
    powerShellAction.isFinished = false;
    using (PowerShell ps = PowerShell.Create())
    {
        ps.AddScript(commandStr); // adding the script to the powershell script.
        var outputCollection = new PSDataCollection<PSObject>();
        outputCollection.DataAdded += OutputData;
        IAsyncResult result = ps.BeginInvoke<PSObject, PSObject>(null, outputCollection);
        PSDataCollection<PSObject> execRes = await Task.Factory.FromAsync(result, ps.EndInvoke).ContinueWith(t => {
            if (t.IsFaulted) 
            {
                System.Diagnostics.Trace.TraceError("Task faulted with exception: " + t.Exception?.Message);    
            }
            return t.Result;
        }).ConfigureAwait(false);
    }
    return powerShellAction;
}

我使用ContinueWith是为了对原始任务中可能发生的任何异常做出反应。

我之所以建议这样做,是因为您的描述闻起来像是您具有典型的线程锁,这意味着由于异常或上下文同步问题而导致简单的代码无法返回。