c# - 在 Windows 8.1 上使用 task.run 安装巧克力文件的问题
问题描述
我的任务是创建一个工具来帮助轻松设置客户系统。我在 c# 中创建了一个通过 powershell 调用巧克力脚本的函数,我使用 Task.run 创建一个新线程,因此它不会影响 UI 线程,系统工作正常,但我在某些计算机上遇到问题. 我无法访问这些计算机并且对他们的系统了解不多,并且由于时间限制无法访问这些计算机,这无济于事。我知道他们有Windows 8.1。我得到了一个 Windows 10 虚拟机进行测试(我仍然不明白,因为已知这是一个 Windows 8 问题)
这是代码。我知道一个事实(由于有一次我被授予访问这些计算机的权限)它在 Task.Run(() => 任务上停止)
有谁知道 Windows 8.1 上的巧克力或任务是否有任何问题?
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
作为 abool
)。 - 添加
ConfigureAwait(false)
到您的await
以防止 .NET 尝试同步回上下文。 - 更加注意方法内部的异常处理。
- 如果您的方法中不需要它,请不要返回任何东西。
代码(untestet)可能是这样的:
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
它是为了能够对原始任务中可能发生的任何异常做出反应。
我建议这样做是因为您的描述闻起来像您有一个典型的线程锁,这意味着简单的代码不会由于异常或上下文同步问题而返回。
推荐阅读
- templates - 如何使用 .NET CLI 自定义模板获取项目名称的驼峰式版本
- r - 调整单选按钮和滑块后如何刷新绘图?
- c# - 您如何在 xunit 中看到来自控制器的错误
- microsoft-graph-api - 如何在 OpenAPI 中指定将用户添加到组?
- reactjs - 我应该在 useCallback 的依赖数组中包含 setState 吗?
- winapi - 有没有一种简单的方法来获取用于擦除窗口背景的画笔的 RGB?
- intern - 从 Grunt 运行时,如何设置 Intern 的内存大小?
- javascript - javascript image base64 和 php image base64_encode 是不同的
- php - 无法通过传递的输入深度扩展 Laravel Artisan Command
- javascript - 在图表中显示 xrange x 和 x2 值