byte[20] を持つオブジェクトが 1 つのスレッドで BlockingCollection に渡され、別のスレッドが BlockingCollection.Take() を使用して byte[0] を持つオブジェクトを返すという問題があります。これはスレッドの問題だと思いますが、BlockingCollection が並行コレクションであることを考えると、どこで、またはなぜこれが起こっているのかわかりません。
スレッド 2 では、myclass2.mybytes が byte[0] と等しい場合があります。これを修正する方法に関する情報は大歓迎です。
[編集] 元のコード。問題なく動作するように見えた上記のコードを削除したので、時間をかけて元のコードを調べて投稿しました。
MessageBuffer.cs
public class MessageBuffer : BlockingCollection<Message>
{
}
Listener() と ReceivedMessageHandler(object messageProcessor) を持つクラスで
private MessageBuffer RecievedMessageBuffer;
スレッド 1 で
private void Listener()
{
while (this.IsListening)
{
try
{
Message message = Message.ReadMessage(this.Stream, this);
if (message != null)
{
this.RecievedMessageBuffer.Add(message);
}
}
catch (IOException ex)
{
if (!this.Client.Connected)
{
this.OnDisconnected();
}
else
{
Logger.LogException(ex.ToString());
this.OnDisconnected();
}
}
catch (Exception ex)
{
Logger.LogException(ex.ToString());
this.OnDisconnected();
}
}
}
Message.ReadMessage(NetworkStream ストリーム、iTcpConnectClient クライアント)
public static Message ReadMessage(NetworkStream stream, iTcpConnectClient client)
{
int ClassType = -1;
Message message = null;
try
{
ClassType = stream.ReadByte();
if (ClassType == -1)
{
return null;
}
if (!Message.IDTOCLASS.ContainsKey((byte)ClassType))
{
throw new IOException("Class type not found");
}
message = Message.GetNewMessage((byte)ClassType);
message.Client = client;
message.ReadData(stream);
if (message.Buffer.Length < message.MessageSize + Message.HeaderSize)
{
return null;
}
}
catch (IOException ex)
{
Logger.LogException(ex.ToString());
throw ex;
}
catch (Exception ex)
{
Logger.LogException(ex.ToString());
//throw ex;
}
return message;
}
スレッド 2 で
private void ReceivedMessageHandler(object messageProcessor)
{
if (messageProcessor != null)
{
while (this.IsListening)
{
Message message = this.RecievedMessageBuffer.Take();
message.Reconstruct();
message.HandleMessage(messageProcessor);
}
}
else
{
while (this.IsListening)
{
Message message = this.RecievedMessageBuffer.Take();
message.Reconstruct();
message.HandleMessage();
}
}
}
PlayerStateMessage.cs
public class PlayerStateMessage : Message
{
public GameObject PlayerState;
public override int MessageSize
{
get { return 12; }
}
public PlayerStateMessage()
: base()
{
this.PlayerState = new GameObject();
}
public PlayerStateMessage(GameObject playerState)
{
this.PlayerState = playerState;
}
public override void Reconstruct()
{
this.PlayerState.Poisiton = this.GetVector2FromBuffer(0);
this.PlayerState.Rotation = this.GetFloatFromBuffer(8);
base.Reconstruct();
}
public override void Deconstruct()
{
this.CreateBuffer();
this.AddToBuffer(this.PlayerState.Poisiton, 0);
this.AddToBuffer(this.PlayerState.Rotation, 8);
base.Deconstruct();
}
public override void HandleMessage(object messageProcessor)
{
((MessageProcessor)messageProcessor).ProcessPlayerStateMessage(this);
}
}
Message.GetVector2FromBuffer(int bufferlocation) これは例外がスローされる場所です。これは、this.Buffer が byte[20] である必要があるのに byte[0] であるためです。
public Vector2 GetVector2FromBuffer(int bufferlocation)
{
return new Vector2(
BitConverter.ToSingle(this.Buffer, Message.HeaderSize + bufferlocation),
BitConverter.ToSingle(this.Buffer, Message.HeaderSize + bufferlocation + 4));
}