从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