Синхронизированное возвращающее значение метода, учитывающего порядок вызовов - PullRequest
1 голос
/ 07 января 2011

У меня есть метод, который отправляет 3 веб-запроса на устройство, которое заставляет его отправлять смс.2 первых запроса соответственно устанавливают получателя смс и тело сообщения.Третий запускает отправку.

Понятно, что этот метод должен быть синхронизирован, так как гоночные вызовы полностью испортят процесс конфигурации sms.

Конечно, это очень хорошо решается следующим образом:

private object _smsLock  
private bool SendSmsSync(string recipientNumber, string body)  
{  
    lock(_smsLock)  
    {  
        // 3 web requests are sent here  
        // false is returned if something goes wrong
        return true;
    }  
}

Однако недостатком этого решения является то, что мы не имеем абсолютно никакого контроля над порядком, в котором будут выполняться одновременные вызовы.

Большой кусок кода, включая Queue, ManualResetEvents и потокимог конечно это сделать.Но я все еще хотел бы знать, знает ли кто-нибудь о более простом способе сделать это.

Обсудить:)

Ответы [ 2 ]

1 голос
/ 07 января 2011

Это похоже на разумный способ защитить отправку сообщения.Это предотвратит выход из строя самих сообщений.

Если вам нужно синхронизировать несколько сообщений, одним из вариантов будет использование сценария «производитель / потребитель».Это позволит вам иметь один поток, который ничего не делает, кроме как выкачивает эти сообщения, в порядке.

public class Sms
{
    public class SmsMessage
    {
        public int RecipientNumber { get; private set; }
        public string Body { get; private set; }
        public Sms(int recipient, string body) 
        { 
           this.RecipientNumber = recipient;
           this.Body = body;
        }
    }

    // Include your code above...

    private BlockingCollection<SmsMessage> messageQueue = new BlockingCollection<SmsMessage>();

     public void Send(SmsMessage message)
     {
           messageQueue.Add(message);
     }

     // Permanently stop sending messages...
     public void Stop()
     {
           messageQueue.CompleteAdding();
     }

     public Sms()
     {
         // Spawn a thread to pump messages as they arrive
         Task.Factory.StartNew( () =>
             {
                  foreach(var message in messageQueue.GetConsumingEnumerable())
                      SendSmsSync(message.RecipientNumber, message.Body);
             }, TaskCreationOptions.LongRunning);
     }
}

При этом вы можете просто создать экземпляр Sms и вызвать Send для постановки сообщения в очередь.Сообщения всегда будут отправляться по порядку.

Кроме того, это должно исключить необходимость блокировки, указанной выше, поскольку сообщения всегда отправляются в одном потоке пользователя.

0 голосов
/ 07 января 2011

Самый простой и логичный ответ, безусловно, должен быть «не делай этого».

То есть: если вам нужно выполнить три вызова последовательно *, не помещайте их в отдельные потоки - просто пишите код последовательно.

(* Хорошо, поэтому первое и второе могут быть распараллелены, но почему?)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...