[英]F# Async Task Cancellation without Token
我正在嘗試解析數百個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
}
異步會在指定的操作(例如return!
上取消return!
, let!
,或do!
; 它們不僅會殺死處於未知狀態的線程,這通常是不安全的。 如果您希望異步停止,則可以例如:
遞歸並通過return!
進行迭代return!
。 調用者將向Async.RunSynchronously
提供CancellationToken
,並在作業完成時捕獲所產生的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
如果取消的確切時間相關,我相信第二種方法可能並不安全,因為在其他線程看到變量更改之前可能會有所延遲。 這似乎無關緊要。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.