循环任务在Try/Catch中提交:后台Submitter线程异常捕获与休眠需求咨询
Great question! Let's tackle this scenario step by step—you want your submitter background task to process jobs, pause while tasks run, sleep until the next heartbeat, and safely handle exceptions from each thread. Your current fire-and-forget approach with Task.Run misses the waiting and exception handling pieces, so here's a robust solution tailored to VB.NET:
Core Approach
The key fixes are:
- Wait for tasks to finish before moving to the next heartbeat (so your submitter doesn't spin uselessly)
- Catch exceptions per task to avoid one failed job taking down others
- Use async/await to cleanly handle pauses without blocking threads
Updated Code Implementation
First, make your submitter method async (required for Await):
Async Sub StartSubmitter() ' Assume sdr.read() checks for pending tasks (triggered by heartbeat logic) While sdr.Read() Dim pendingTasks As New List(Of Task)() ' Collect all tasks to run (adjust if you process one task per iteration) Do While sdr.Read() ' Capture loop variables locally to avoid closure issues Dim currentProcessKey = sProcessKey Dim currentPQID = iPQID ' Wrap task execution in try/catch to handle individual exceptions Dim task = Task.Run(Sub() Try Dim oBackground As New Background() CallByName(oBackground, currentProcessKey, CallType.Method, currentPQID) Catch ex As Exception ' Replace with your error handling: logging, alerting, etc. Console.WriteLine($"Task failed (PQID: {currentPQID}): {ex.Message}") ' Optional: Log full stack trace ' Logger.Error(ex, "Background task execution failed") End Try End Sub) pendingTasks.Add(task) Loop ' Wait for ALL tasks to complete before proceeding ' This pauses the submitter until all jobs finish Await Task.WhenAll(pendingTasks) ' Sleep until the next heartbeat (adjust interval to your needs) Await Task.Delay(TimeSpan.FromMinutes(5)) End While End Sub
Key Details Explained
Async/Await for Pausing
Await Task.WhenAll(pendingTasks)tells the submitter to pause execution until every task in the list finishes. This replaces your infinite loop with intentional waiting.Await Task.Delay(...)puts the submitter to sleep for your configured heartbeat interval—no busy waiting, just efficient thread usage.
Per-Task Exception Handling
- Wrapping each task's logic in a
Try-Catchensures that a single failed job won't crash the entire submitter or other tasks. You can log errors, retry failed jobs, or trigger alerts here without affecting other work.
- Wrapping each task's logic in a
Closure Safety
- Capturing
sProcessKeyandiPQIDinto local variables (currentProcessKey,currentPQID) inside the loop prevents VB.NET's closure behavior from overwriting values before the task runs. This is a common pitfall with loop-bound tasks.
- Capturing
Thread Safety Compliance
- Since you confirmed your tasks are thread-safe, running them in parallel with
Task.Runis perfectly safe—this approach leverages parallelism while keeping the submitter under control.
- Since you confirmed your tasks are thread-safe, running them in parallel with
Alternative: Single Task Per Iteration
If you process one task per sdr.read() call instead of batches, simplify the code to:
Async Sub StartSubmitter() While sdr.Read() Dim currentProcessKey = sProcessKey Dim currentPQID = iPQID Await Task.Run(Sub() Try Dim oBackground As New Background() CallByName(oBackground, currentProcessKey, CallType.Method, currentPQID) Catch ex As Exception Console.WriteLine($"Task failed (PQID: {currentPQID}): {ex.Message}") End Try End Sub) ' Sleep after each task completes Await Task.Delay(TimeSpan.FromSeconds(30)) End While End Sub
This waits for each individual task to finish before sleeping, which works if you don't need parallel processing.
内容的提问来源于stack exchange,提问作者dwneder

