@@ -325,14 +325,14 @@ public virtual async Task SendSms(string messageText, string phoneNumber)
325325 var from = appSettings .Sms ! .FromPhoneNumber ! ;
326326
327327 // Enqueue the job - this returns immediately
328- backgroundJobClient .Enqueue <PhoneServiceJobsRunner >(x => x .SendSms (phoneNumber , from , messageText , default ));
328+ backgroundJobClient .Enqueue <PhoneServiceJobsRunner >(x => x .SendSms (phoneNumber , from , messageText ));
329329}
330330```
331331
332332** Key points:**
333333- ` backgroundJobClient.Enqueue<T>() ` schedules the job to run in the background
334334- The method returns ** immediately** - the user doesn't wait
335- - The ` default ` parameter is a placeholder for the ` CancellationToken ` (Hangfire will provide it)
335+ - Hangfire will automatically provide the ` PerformContext ` and ` CancellationToken ` parameters to the job runner method
336336
337337#### Step 2: The Job Runner Executes the Task
338338
@@ -344,7 +344,9 @@ public partial class PhoneServiceJobsRunner
344344 [AutoInject ] private ServerExceptionHandler serverExceptionHandler = default ! ;
345345
346346 [AutomaticRetry (Attempts = 3 , DelaysInSeconds = [30 ])]
347- public async Task SendSms (string phoneNumber , string from , string messageText , CancellationToken cancellationToken )
347+ public async Task SendSms (string phoneNumber , string from , string messageText ,
348+ PerformContext context = null ! ,
349+ CancellationToken cancellationToken = default )
348350 {
349351 try
350352 {
@@ -357,32 +359,39 @@ public partial class PhoneServiceJobsRunner
357359 var smsMessage = MessageResource .Create (messageOptions );
358360
359361 if (smsMessage .ErrorCode is not null )
360- throw new InvalidOperationException (smsMessage .ErrorMessage )
361- .WithData (new () { { " Code" , smsMessage .ErrorCode } });
362+ throw new InvalidOperationException (smsMessage .ErrorMessage ).WithData (new () { { " Code" , smsMessage .ErrorCode } });
362363 }
363364 catch (Exception exp )
364365 {
365- serverExceptionHandler .Handle (exp , new () { { " PhoneNumber" , phoneNumber } });
366-
366+ serverExceptionHandler .Handle (exp , new ()
367+ {
368+ { " PhoneNumber" , phoneNumber },
369+ { " JobId" , context .BackgroundJob .Id }
370+ });
367371 if (exp is not KnownException && cancellationToken .IsCancellationRequested is false )
368372 throw ; // To retry the job
369373 }
370- }
371- }
372- ```
373-
374374** Key features : **
375375
3763761 . ** AutomaticRetry ** : If the job fails , Hangfire automatically retries it
377377 - `Attempts = 3 `: Try up to 3 times
378378 - `DelaysInSeconds = [30 ]`: Wait 30 seconds between retries
379379 - This is perfect for SMS tokens that expire after 2 minutes
380380
381- 2 . ** Exception Handling** :
382- - Logs the error with context (` PhoneNumber ` )
381+ 2. **Hangfire -Provided Parameters **: The method accepts two special parameters that Hangfire automatically provides :
382+ - `PerformContext context `: Provides access to job metadata (like `JobId `, `BackgroundJob `, etc .)
383+ - `CancellationToken cancellationToken `: Signals when the job should be cancelled (e .g ., server shutdown )
384+ - These parameters have default values (`null ! ` and `default `) so Hangfire can invoke the method
385+
386+ 3 . ** Exception Handling ** :
387+ - Logs the error with context (`PhoneNumber `, `JobId `)
383388 - For unknown exceptions , re - throws to trigger retry
384389 - For known exceptions (business logic errors ), doesn 't retry
385390
391+ 4 . ** CancellationToken ** : Even background jobs support cancellation (e .g ., if the server is shutting down )
392+
393+ ** Important ** : Inside background job , there is ** NO ** `IHttpContextAccessor ` or `User ` object available . So if user context is needed , it must be passed as parameters to the job method .
394+
3863953 . ** CancellationToken ** : Even background jobs support cancellation (e .g ., if the server is shutting down )
387396
388397** Important ** : Inside background job , there is ** NO ** `IHttpContextAccessor ` or `User ` object available . So if user context is needed , it must be passed as parameters to the job method .
0 commit comments