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