带有记录和锁的异步实现

async implementation with records and lock

我担心我的代码中存在竞争条件情况。

我有这个从数据库中获取信息的函数:

        public async Task ExecuteBroadcasts()
    {
        List<Broadcast> broadcasts =_iSMSFetcherUnitOfWork.GetAllBroadCastsInPastTimeThatDidntRun();

        foreach (Broadcast broadcast in broadcasts)
        {
            foreach (SenderPhone sender in broadcast.SenderPhoneList.SenderPhones)
            {
                foreach (ReceiverPhone receiverPhone in broadcast.RecipeintPhoneList.ReceiverPhones)
                { 
                   var tasks=  broadcast.RecipeintPhoneList.ReceiverPhones.Select(receiverPhone => _iSMSProcessorAndSender.ProcessSMSes(new PreProcessedSMS(sender.Phone, receiverPhone, broadcast.SMSTemplate))).ToArray();
                   await Task.WhenAll(tasks); 
                }
            }
    
        }
    } 

这种类型'PreProcessedSMS'是一条记录。 ProcessSMSes 是一个函数,它将从数据库中获取的信息发送到 SMS 提供商。下面是这个函数的内容。

 public async Task ProcessSMSes(PreProcessedSMS preProcessedSMS)
    { 
        _iSMSExpressionInterpreter.ReceiverPhone = preProcessedSMS.receiverPhoneObj;

        object sync = new object();

        string smsBody = string.Empty;

        lock (sync) smsBody = preProcessedSMS.sMSTemplate;

        Task longRunning = Task.Factory.StartNew(() =>
        { 
            smsBody = _iSMSExpressionInterpreter.TranslateSpinner(preProcessedSMS.sMSTemplate);
        });

        await longRunning.ContinueWith(async (sms) =>
        {
            smsBody = _iSMSExpressionInterpreter.TranslateFirstName(smsBody);
            smsBody = _iSMSExpressionInterpreter.TranslateLastName(smsBody);
            smsBody = _iSMSExpressionInterpreter.TranslateCustom(smsBody);
            smsBody = _iSMSExpressionInterpreter.TranslateUnsubscribe(smsBody);
            await _iSMSDispatcher.SendSMS(new SMSRecord(preProcessedSMS.senderPhone, preProcessedSMS.receiverPhoneObj.Phone, smsBody));

        }, TaskContinuationOptions.NotOnFaulted); 

        longRunning.Start(); 
    } 

我锁定了 'smsBody' 参数,因为担心下一个函数执行会为其设置不同的值。我对实施持谨慎态度。在不遇到可能的竞争条件的情况下高效执行代码的最佳方法是什么。

更新:

  public async Task ProcessSMSes(PreProcessedSMS preProcessedSMS)
    {  
        await Task.Run(async () =>
        {
            _iSMSExpressionInterpreter.ReceiverPhone = preProcessedSMS.receiverPhoneObj;
            string smsBody = _iSMSExpressionInterpreter.TranslateSpinner(preProcessedSMS.sMSTemplate);
            smsBody = _iSMSExpressionInterpreter.TranslateFirstName(smsBody);
            smsBody = _iSMSExpressionInterpreter.TranslateLastName(smsBody);
            smsBody = _iSMSExpressionInterpreter.TranslateCustom(smsBody);
            smsBody = _iSMSExpressionInterpreter.TranslateUnsubscribe(smsBody);
            await _iSMSDispatcher.SendSMS(new SMSRecord(preProcessedSMS.senderPhone, preProcessedSMS.receiverPhoneObj.Phone, smsBody));
        });
    } 

locks 仅在其他所有内容也使用相同的 lock 时才有效。在这种情况下,您将锁定一个局部变量,它什么都不做。您不能使用锁来防止任何其他代码更改任何内容。在这种情况下,您 可以 sMSTemplate 的实现中使用 lock,这样每次 read/written,它都使用 lock ,但这似乎很奇怪。我建议明智地使用锁,其中多线程访问是 预期的,而不是“出于恐惧”。

旁注: