我正在尝试解析数百个C源文件,将数十个软件信号变量映射到物理硬件引脚的名称。我试图在F#
中异步执行此操作IndirectMappedHWIO
|> Seq.map IndirectMapFromFile //this is the function with the regex in it
|> Async.Parallel
|> Async.RunSynchronously
问题在于我无法弄清楚如何传递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
}
答案 0 :(得分:1)
Asyncs取消指定的操作,例如return!
,let!
或do!
;他们不只是在任何未知状态下杀死线程,这通常不安全。如果你想让你的asyncs停下来,他们可以举例如:
是递归的,并通过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
如果取消的确切时间是相关的,我相信第二种方法可能不安全,因为在其他线程看到变量变化之前可能会有延迟。这似乎并不重要。