從MS had said that both APM and EAP are outdated開始,在.NET Framework中推薦使用TAP進行異步編程。然後我想轉換從APM我的代碼爲TAP:將APM迭代調用轉換爲TAP
public class RpcHelper
{
public void DoReadViaApm(IRpc rpc, BlockingCollection<ArraySegment<byte>> bc)
{
byte[] buf = new byte[4096];
rpc.BeginRead(buf, 0, buf.Length,
ar =>
{
IRpc state = (IRpc) ar.AsyncState;
try
{
int nb = state.EndRead(ar);
if (nb > 0)
{
bc.Add(new ArraySegment<byte>(buf, 0, nb));
}
}
catch (Exception ignored)
{
}
finally
{
DoReadViaApm(state, bc);
}
},
rpc);
}
public void DoReadViaTap(IRpc rpc, BlockingCollection<ArraySegment<byte>> bc)
{
Task.Factory.StartNew(() =>
{
while (true)
{
Task<byte[]> task = rpc.ReadAsync();
try
{
task.Wait(-1);
if (task.Result != null && task.Result.Length > 0)
{
bc.Add(new ArraySegment<byte>(task.Result));
}
}
catch (Exception ignored)
{
}
}
}, TaskCreationOptions.LongRunning);
}
}
public interface IRpc
{
IAsyncResult BeginRead(byte[] buffer, int offset, int size, AsyncCallback callback, Object state);
int EndRead(IAsyncResult asyncResult);
Task<byte[]> ReadAsync();
}
的TAP方法DoReadViaTap()使用TaskCreationOptions.LongRunning,它看起來非常難看。我可以讓DoReadViaTap()看起來更像DoReadViaApm()嗎?
你的代碼看起來更好,但不是我所期望的。我想殺死長時間運行的任務,因爲DoReadViaApm()很快就會使用IO線程。 –
你的意思是由'Task.Factory.StartNew()'創建的任務?您可以使用取消標記來檢查該任務是否應該取消。 [示例](http://stackoverflow.com/a/19932396/2300387) –
'try'去了哪裏?沒有它,catch就不會編譯。 – svick