まず、私は統一を使用しています。 .NET 3.5に悩まされています。私は現在、Socket
オブジェクトの非同期メソッド(E.G. BeginReceive
、BeginAccept
、BeginReceiveFrom
など)を使用するサーバープログラムに取り組んでいます。サーバーがクライアントからパケットを受信すると、このパケットはワーカースレッドで受信されます。今私はワーカースレッド上にいくつかのデータが残っているので、私が指定した関数を使ってこのデータをメインスレッドに処理させたい。そして、私はそれをこのように使用することになりFIFOプログラミングされたメインスレッドディスパッチャ?
using System;
using System.Threading;
using System.Collections;
using System.Collections.Generic;
public class MyDispatcherClass
{
public delegate void MyDel();
private readonly Queue<MyDel> commands = new Queue<MyDel>();
Object lockObj = new object();
public void Add(MyDel dc)
{
lock (lockObj)
{
commands.Enqueue (dc);
}
}
public void Invoke()
{
lock (lockObj)
{
while (commands.Count > 0)
{
commands.Dequeue().Invoke();
}
}
}
}
::私はことを実現し、いくつかの研究の後
// As a global variable:
MyDispatcherClass SomeDispatcher = new MyDispatcherClass();
//The function that I want to call:
public void MyFunction (byte[] data)
{
// Do some stuff on the main thread
}
//When I receive a message on a worker thread I do that:
SomeDispatcher.Add (()=> MyFunction (byte[] data)); //Asuume that "data" is the message I received from a client
//Each frame on the main thread I call:
SomeDispatcher.Invoke();
を、私はlock
文が%100 FIFOの実装を保証するものではないことがわかりました。これは私の望むものではありませんが、時にはこれがサーバーの故障の原因になることがあります。データがクライアントから受け取ったのと同じ順序で処理されることを保証する%100という同じ結果を達成したいと思います。どうすればそれを達成できますか?
あなたは1人のクライアントで1人のクライアントからすべてのデータを取得しますか?もしそうなら、ディスパッチャーに 'AddRange'メソッドを追加することができます。ディスパッチャーは、引数として' IEnumerable 'をとり、それらを同じロック本体に追加します。 –
ArgusMagnus
私は以前これを調べました。私は各クライアント1からデータを受け取り、SomeDispatcher.Addを呼び出すスレッドは、各クライアント(これはMicrosoftが実装した実装です)でも常に変化している可能性があります。 – None