2011-01-07 11 views
1

私は3つのWebリクエストをデバイスに送信し、それによってデバイスにSMSを送信する方法があります。 2つの最初の要求はそれぞれ、受信者とメッセージ本文を設定します。 3番目がディスパッチを開始します。値を返す同期された "呼び出し順序認識"メソッド

レースコールが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、threadsを含む重いコードを作成することはもちろん可能です。しかし、私はまだ誰かがそれを行うより簡単な方法を認識しているかどうかを知りたいと思います。

は議論:)

答えて

1

これは、メッセージの送信を保護するために合理的な方法のように思えます。メッセージ自体が乱れることを防ぎます。

複数のメッセージにまたがって同期を行う必要がある場合は、プロデューサ/コンシューマのシナリオを使用することもできます。これにより、これらのメッセージを順番に送り出すだけの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を呼び出してメッセージをエンキューすることができます。メッセージは常に順番に送信されます。

また、メッセージは常に単一のコンシューマスレッドで送信されるため、これにより、上記のロックが不要になります。

+0

は、私が聞いたことがなかったSystem.Threading.Tasksに向かって私をリードいただきありがとうございます(私に恥!) 。 –

+0

@Remy:BTW、詳細を知りたければ、TPL(それと関連する名前空間)の** long **シリーズはhttp://reedcopsey.com/series/parallelism-in-net4/ –

0

最も単純で最も論理的な答えは、必ず「しないでください」です。

これは:連続して3回コールする必要がある場合は、それらを別々のスレッドに置かないでください。コードを順番に書きます。

(* [OK]を、第一及び第二の並列化することができるよう、なぜ?)

+0

にあります。 3つの呼び出しを別々のスレッドにする必要はありません、au contraire!このシナリオでは、私のSendSmsメソッドに複数のスレッドが同時にアクセスできるようになっています。ごめんなさい。 –

関連する問題