2011-01-07 72 views
1

我有一种方法可以向设备发送3个Web请求,这会使其发送一条短信。 2个第一个请求分别设置了短信收件人和邮件正文。第三次触发派遣。同步的“呼叫定制感知”方法返回值

很明显,这种方法必须同步,因为竞争将彻底搞乱短信配置过程。

这当然是非常漂亮的解是这样的:

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和线程的大量代码当然可以做到。但我仍然想知道是否有人知道更简单的方法来做到这一点。

讨论:)

回答

1

这似乎是一个合理的方法来保护消息的发送。它将防止消息本身发生故障。

如果您需要跨多个消息进行同步,则一种选择是使用生产者/消费者方案。这将允许你有一个单独的线程,只是将这些消息按顺序排除。

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实例,并调用发送给排队的消息。邮件将始终按顺序发送。

此外,这应消除上面的锁定的需要,因为消息始终在单个使用者线程中发送。

+0

谢谢你带领我走向System.Threading.Tasks,这是我从来没有听说过(可耻的是我!) 。 – 2011-01-07 03:22:34

+0

@Remy:顺便说一句,如果你想要的细节,我有一个关于TPL(和相关命名空间)的** long **系列:http://reedcopsey.com/series/parallelism-in-net4/ – 2011-01-07 22:21:13

0

最简单也是最合乎逻辑的答案应该是“不要那么做”。

即:如果您需要按顺序进行三次调用*,请勿将它们放在单独的线程上 - 只需按顺序编写代码即可。

(*好了,第一和第二可以被并行化,但为什么?)