在 windows 8.1 上使用 task.run 安装巧克力文件时出现问题
Problem with installing chocolatey files with task.run on windows 8.1
我的任务是创建一个工具来帮助轻松设置客户系统。我创建了一个通过 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 的虚拟机以继续尝试调试自己。欢迎任何其他建议。
很遗憾,我无法确保我的建议是正确的。主要原因是,我不知道 PowerShellAction
应该是什么。我在这里假设 PowerShell
是 System.Management.Automation.PowerShell
。
我建议几件事:
- 您的代码无法编译有几个原因:您的方法的第一行没有
var
或类型声明,并且方法调用不会因为添加 string
而起作用关键词。以后请尽量避免粘贴像您这样的代码,因为重建您的示例非常困难。
- 不要将 UI 控件绕过异步方法,而是使用所需的值(例如
box.IsChecked
作为 bool
)。
- 将
ConfigureAwait(false)
添加到您的 await
以防止 .NET 尝试同步回上下文。
- 更加注意您的方法中的异常处理。
- 如果您的方法中不需要任何东西,请不要 return。
代码(未测试)可能是这样的:
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
是为了能够对原始任务中可能发生的任何异常做出反应。
我建议这样做是因为你的描述闻起来像你有一个典型的线程锁,这意味着简单的代码不会由于异常或上下文同步问题而返回。
我的任务是创建一个工具来帮助轻松设置客户系统。我创建了一个通过 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 的虚拟机以继续尝试调试自己。欢迎任何其他建议。
很遗憾,我无法确保我的建议是正确的。主要原因是,我不知道 PowerShellAction
应该是什么。我在这里假设 PowerShell
是 System.Management.Automation.PowerShell
。
我建议几件事:
- 您的代码无法编译有几个原因:您的方法的第一行没有
var
或类型声明,并且方法调用不会因为添加string
而起作用关键词。以后请尽量避免粘贴像您这样的代码,因为重建您的示例非常困难。 - 不要将 UI 控件绕过异步方法,而是使用所需的值(例如
box.IsChecked
作为bool
)。 - 将
ConfigureAwait(false)
添加到您的await
以防止 .NET 尝试同步回上下文。 - 更加注意您的方法中的异常处理。
- 如果您的方法中不需要任何东西,请不要 return。
代码(未测试)可能是这样的:
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
是为了能够对原始任务中可能发生的任何异常做出反应。
我建议这样做是因为你的描述闻起来像你有一个典型的线程锁,这意味着简单的代码不会由于异常或上下文同步问题而返回。