某些System.Threading.Tasks.Task构造函数将a CancellationToken作为参数:
CancellationTokenSource source = new CancellationTokenSource();
Task t = new Task (/* method */, source.Token);
Run Code Online (Sandbox Code Playgroud)
令我感到困惑的是,从方法体内部无法实际获取传入的令牌(例如,没有什么比这样Task.CurrentTask.CancellationToken).必须通过某种其他机制提供令牌,例如状态对象或在lambda中捕获.
那么在构造函数中提供取消令牌的目的是什么呢?
我正在编写一个cmdlet(在PowerShell中),它负责将记录写入数据库.使用条件命令行,似乎我必须定义四个不同的参数集.
这样做有更多的方法吗?
细节
cmdlet的参数是:
ComputerName (要连接的SQL服务器)Path (数据的位置)Xml (原始数据本身)UserNamePassword UseIntegratedSecurity (而不是用户名/密码,使用当前凭据)Path并且Xml是互斥的,和UserName/ Password和UseIntegratedSecurity是互斥的.
为了正确连接,似乎我必须定义四个不同的参数集,例如:
function Install-WidgetData
{
[CmdletBinding()]
PARAM
(
[Parameter(ParameterSetName="Xml_AutoConnect", Mandatory=$True)]
[Parameter(ParameterSetName="Xml_ManualConnect", Mandatory=$True)]
[Parameter(ParameterSetName="Path_AutoConnect", Mandatory=$True, )]
[Parameter(ParameterSetName="Path_ManualConnect", Mandatory=$True)]
[ValidateNotNullOrEmpty()]
[string[]] $ComputerName,
[Parameter(ParameterSetName="Path_AutoConnect", Mandatory=$True)]
[Parameter(ParameterSetName="Path_ManualConnect", Mandatory=$True)]
[ValidateNotNullOrEmpty()]
[string] $Path,
[Parameter(ParameterSetName="Xml_AutoConnect", Mandatory=$True)]
[Parameter(ParameterSetName="Xml_ManualConnect", Mandatory=$True)]
[ValidateNotNullOrEmpty()]
[string[]] $Xml,
[Parameter(ParameterSetName="Xml_AutoConnect")]
[Parameter(ParameterSetName="Path_AutoConnect")]
[switch] $UseIntegratedSecurity,
[Parameter(ParameterSetName="Xml_ManualConnect")]
[Parameter(ParameterSetName="Path_ManualConnect")]
[ValidateNotNullOrEmpty()]
[string] $UserName,
[Parameter(ParameterSetName="Xml_ManualConnect")]
[Parameter(ParameterSetName="Path_ManualConnect")]
[ValidateNotNullOrEmpty()]
[string] $Password,
)
Run Code Online (Sandbox Code Playgroud) TPL具有许多TaskContinuationOptions值,用于控制任务执行的环境.例如,TaskContinuationOptions.NotOnCanceled阻止任务在其父项被取消时运行.
但是,这些任务状态过滤器都不适用于多任务延续.你做不了类似的事情:
TaskFactory f = new TaskFactory();
Task t1 = new Task (() => Thread.Sleep (5000));
Task t2 = new Task (() => Thread.Sleep (4000));
Task t3 = f.ContinueWhenAll (new Task[] { t1, t2 },
(tasks) => { ... },
TaskContinuationOptions.OnlyOnRanToCompletion);
Run Code Online (Sandbox Code Playgroud)
你最终得到的错误是, "It is invalid to exclude specific continuation kinds for continuations off of multiple tasks."
我不明白为什么这个条件会被排除在API之外.为什么只有当所有前提都以特定状态结束时才希望任务运行,这不是一个完全有效的用例?
我正在开发一个名为Merge-Xsd可以合并类似XML模式的cmdlet .它采用路径列表,加载模式,合并它们,并生成XMLDocument输出.
特定文件名的所有模式都被认为是"相似的",所以我正在做的是获取特定目录结构中的所有子项,根据文件名对它们进行分组,然后尝试将它们传递给我的自定义小命令.
将它们分组很容易:
$grouping = Get-ChildItem -Recurse -Filter *.xsd |
Group-Object -Property Name -AsHashTable -AsString
Run Code Online (Sandbox Code Playgroud)
但是,将它们作为同一管道的一部分进行处理则不然.我已经接近这个了:
$grouping.Keys |
ForEach-Object { ($grouping[$_] |
Select-Object -ExpandProperty FullName | Merge-Xsd).Save("C:\Out\$_") }
Run Code Online (Sandbox Code Playgroud)
但我真正希望能够做的是ForEach-Object直接使用Group-Object迭代每个组项,从而消除了对单独$grouping变量的需要.
我如何使用ForEach-Object获取键/值对同时保持每个Merge-Xsd作用域调用到该特定键/值对?
20150224更新:
该Merge-Xsd选项设置非常简单:
NAME
Merge-Xsd
SYNTAX
Merge-Xsd [-Path] <string[]> [<CommonParameters>]
Run Code Online (Sandbox Code Playgroud)
它实际上只是用于一次性抛出一堆文件并将它们合并为单个输出,这是一个XmlDocument.(我模拟了输出ConvertTo-Xml.)