Multithreading 无令牌异步任务取消

Multithreading 无令牌异步任务取消,multithreading,asynchronous,f#,task,Multithreading,Asynchronous,F#,Task,我试图解析数百个C源文件,将数十个软件信号变量映射到物理硬件引脚的名称。我试图在F中异步地完成这项工作# 问题是我无法确定如何传入CancellationToken以结束任务。每个任务读取大约300个C文件,因此我希望能够在正则表达式匹配时立即停止任务的执行。我尝试使用Thread.CurrentThread.Abort(),但似乎不起作用。关于如何为每个任务传递CancellationToken有什么想法吗?或者根据条件取消任务的任何其他方式 let IndirectMapFromFile p

我试图解析数百个C源文件,将数十个软件信号变量映射到物理硬件引脚的名称。我试图在F中异步地完成这项工作#

问题是我无法确定如何传入CancellationToken以结束任务。每个任务读取大约300个C文件,因此我希望能够在正则表达式匹配时立即停止任务的执行。我尝试使用
Thread.CurrentThread.Abort()
,但似乎不起作用。关于如何为每个任务传递CancellationToken有什么想法吗?或者根据条件取消任务的任何其他方式

let IndirectMapFromFile pin = 
async {    
    let innerFunc filename = 
        use streamReader = new StreamReader (filePath + filename)
        while not streamReader.EndOfStream do
            try
                let line1 = streamReader.ReadLine()
                streamReader.ReadLine() |> ignore
                let line2 = streamReader.ReadLine()

                if(obj.ReferenceEquals(line2, null)) then
                    Thread.CurrentThread.Abort()  //DOES NOT WORK!!
                else    
                    let m1 = Regex.Match(line1, @"^.*((Get|Put)\w+).*$");
                    let m2 = Regex.Match(line2, @"\s*return\s*\((\s*" + pin.Name + "\s*)\);");
                    if (m1.Success && m2.Success) then
                        pin.VariableName <- m1.Groups.[1].Value
                        Thread.CurrentThread.Abort() //DOES NOT WORK!!
                    else
                        ()
            with
            | ex -> ()
        ()

    Directory.GetFiles(filePath, "Rte*") //all C source and header files that start with Rte
    |> Array.iter innerFunc
}
让IndirectMapFromFile引脚=
异步{
让innerFunc文件名=
使用streamReader=新streamReader(文件路径+文件名)
而不是streamReader.EndOfStream
尝试
让line1=streamReader.ReadLine()
streamReader.ReadLine()|>忽略
让line2=streamReader.ReadLine()
如果(对象引用等于(第2行,null)),则
Thread.CurrentThread.Abort()//不工作!!
其他的
设m1=Regex.Match(第1行,@“^.*((Get | Put)\w+.*$”);
让m2=Regex.Match(第2行,@“\s*返回\s*\((\s*“+pin.Name+”\s*)\);”;
如果(m1.Success&&m2.Success)那么
pin.VariableName()
()
Directory.GetFiles(filePath,“Rte*”)//所有以Rte开头的C源文件和头文件
|>Array.iter innerFunc
}

异步取消指定的操作,例如返回
让我来,或
执行;它们不只是在任何未知状态下杀死线程,这通常是不安全的。如果希望异步停止,它们可以是,例如:

  • 通过
    return进行递归和迭代。调用方将提供一个
    CancellationToken
    Async.RunSynchronously
    ,并在作业完成时捕获生成的
    OperationCanceledException

  • 检查一些线程安全状态并根据它决定停止

请注意,这些实际上是同一件事:遍历数据的工作人员检查正在发生的事情,并以有序的方式取消。换句话说,很明显他们什么时候检查取消

使用异步取消可能会导致如下结果:

let canceler = new System.Threading.CancellationTokenSource()
let rec worker myParameters =
    async {
        // do stuff
        if amIDone() then canceler.Cancel()
        else return! worker (...) }

let workers = (...) |> Async.Parallel

try Async.RunSynchronously(workers, -1, canceler.Token) |> ignore
with :? System.OperationCanceledException -> ()
let keepGoing = ref true
let rec worker myParameters =
    if !keepGoing then
        // do stuff
        if amIDone() then keepGoing := false
        worker (...)

let makeWorker initParams = async { worker initParams }
// make workers
workers |> Async.Parallel |> Async.RunSynchronously |> ignore
从公共状态停止可能如下所示:

let canceler = new System.Threading.CancellationTokenSource()
let rec worker myParameters =
    async {
        // do stuff
        if amIDone() then canceler.Cancel()
        else return! worker (...) }

let workers = (...) |> Async.Parallel

try Async.RunSynchronously(workers, -1, canceler.Token) |> ignore
with :? System.OperationCanceledException -> ()
let keepGoing = ref true
let rec worker myParameters =
    if !keepGoing then
        // do stuff
        if amIDone() then keepGoing := false
        worker (...)

let makeWorker initParams = async { worker initParams }
// make workers
workers |> Async.Parallel |> Async.RunSynchronously |> ignore

如果取消的确切时间是相关的,我相信第二种方法可能不安全,因为在其他线程看到变量更改之前可能会有延迟。不过,这在这里似乎并不重要。

当任何一个任务找到匹配项时,您是否要停止所有任务?或者,您是否希望退出阵列。iter该pin成功匹配后?您是否有幸使用
Async.RunSynchronously
重载,该重载使用
CancellationToken
?每个任务彼此独立,它们试图匹配唯一的正则表达式。因此,如果一个任务得到匹配,它应该只取消自己。其他任务应该继续工作,直到找到自己的正则表达式匹配为止。