You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

循环任务在Try/Catch中提交:后台Submitter线程异常捕获与休眠需求咨询

Handling Background Task Execution with Sleep and Exception Handling in VB.NET

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

  1. 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.
  2. Per-Task Exception Handling

    • Wrapping each task's logic in a Try-Catch ensures 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.
  3. Closure Safety

    • Capturing sProcessKey and iPQID into 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.
  4. Thread Safety Compliance

    • Since you confirmed your tasks are thread-safe, running them in parallel with Task.Run is perfectly safe—this approach leverages parallelism while keeping the submitter under control.

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:51:45