私はこれに似たコードを書いています(私はここでstackoverflowに変更したので、おそらくタイプミスがあります)。非同期プロパティのアクセスを待つ
- は私が
Rename()
に値を更新する前にGetName()
結果を送信し、このリスナーにPacketType.Rename
以降PacketType.GetName
を送信し、それが終了する可能性があることを知っています。 "注文"を確実にするために、 ロジックの前に両方のメソッドでロックオブジェクトを使用する必要がありますか?私は実行を呼び出し、Rename()
が と呼ばれ、コードがNetworkStream
からPacketType.GetName
を取得する前に、したがって、Rename()
内の最初の行にロックが常に が呼ばれるべき待つまでBeginReceive()
タスク は、次のメッセージを読んで起動しないと仮定することができますし、電話はGetName()
を待っていますか? 同じ
PacketType.Rename
が一緒に10回送信、その可能Rename()
方法 がで同時に実行されているように、コードのリーチは、Rename()
を待っていたら、次のいずれか を取得するためにExecute()
とバックを実行し、BeginReceive()
上のいずれかによってパケット1 を取得します複数のタスク。 このケースのように値を更新する最新のものはどれですか(すべて の名前が同じです)、または更新された値は の名前のようには関係ありません。- 私の非同期メソッドでサービス/リポジトリパターンを使用して、 データベースに対してCRUDを実行する場合、サービス/リポジトリはローカル変数とメソッドパラメータのみを使用しますが、
MockConnectionHandler
注射された特性として?各タスクは、これらを独立して、同じサービス/リポジトリを実行する他のタスクから保護する必要がありますか? - 明白なことは何も避けてください。
public class Listener : IListener
{
public string Name {get;set;}
public int Connected {get;set;}
...
private async Task Listen()
{
while (!_Token.IsCancellationRequested)
{
tcpClient = await _Listener.AcceptTcpClientAsync().ConfigureAwait(false);
Connected++;
IConnectionHandler connectionHandler = _ClientPool.Receive();
connectionHandler.TcpClient = tcpClient;
connectionHandler.Listener = this; // really is done on the Listener init()
connectionHandler.Init();
}
}
}
public class MockConnectionHandler : IConnectionHandler
{
public string Name {get;set;}
public int Messages {get;set;}
public IListener Listener {get;set;}
public void Init()
{
BeginReceive();
}
private void BeginReceive()
{
var receive = Task.Run(async() =>
{
while (true)
{
readedHeader = await _Stream.ReadAsync(dataHead, 0, headerLength, _DisconnectToken);
// get body length from header.
readedBody = await _Stream.ReadAsync(dataBody, 0, bodyLength, _DisconnectToken);
Task run = Task.Run(() => Execute(headType, dataBody));
}
}, _DisconnectToken)
.ContinueWith(previous =>
{
_EndReceiving = true;
}, TaskContinuationOptions.OnlyOnCanceled);
}
private async Task Execute(PacketType type, byte[] data)
{
switch(packetType)
{
case PacketType.Echo:
await SendAsync(new Bag(PacketType.Echo));
case PacketType.Rename:
await Rename();
case PacketType.GetName:
await GetName();
}
}
private async Task Rename(byte[] data)
{
Name = Encoding.UTF8.GetString(data);
Listener.Name = Encoding.UTF8.GetString(data);
}
private async Task GetName()
{
byte[] data = Encoding.UTF8.GetBytes(Name);
SendAsync(new Bag(PacketType.Echo, data));
}
}
私は悪いですが、 'Execute()'コールを待っていないと思っていましたので、コードを更新して以前の質問で今や意味が分かりました。 – Nauzet