我有一个方法可以向设备发送3个Web请求,这会让它发送短信。 第一个请求分别设置了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和线程在内的大量代码当然可以实现。但我仍然想知道是否有人知道更简单的方法。
讨论:))
答案 0 :(得分: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实例,并调用Send来排队一条消息。消息将始终按顺序发送。
此外,这应该不需要上面的锁定,因为消息总是在一个消费者线程中发送。
答案 1 :(得分:0)
最简单和最合乎逻辑的答案当然应该是“不要那样做”。
即:如果你需要按顺序进行三次调用*,不要将它们放在单独的线程上 - 只需按顺序编写代码即可。
(*好的,所以第一个和第二个可以并行化,但为什么呢?)