这是使用async / await的回调包装方法的正确方法吗?

时间:2016-03-15 03:20:53

标签: c# async-await

我正在开发一个可以在网络上来回发送结构化消息的库。该库有一个Send方法,需要Action作为回调。当调用Send时,消息被发送到服务器,当收到对该消息的响应时,检索并执行存储的回调。

这一切都很完美,但我想添加一个包裹SendAsync的{​​{1}}方法,以便可以使用async / await而不是直接传递Send。我已经开始工作,但我不知道如果我正确地做到了,或者我以后会遇到问题。有一条线特别困扰我。

Action看起来像这样:

Send

异步public void Send(Packet packet, Action<Response> callback) { if (packet is Request) { RegisterResponseCallback(packet, callback); } Send(packet); } 如下所示:

SendAsync

我用这段代码调用了public Task<Response> SendAsync(Request request) { var tcs = new TaskCompletionSource<Response>(); Send(request, (response) => { tcs.TrySetResult(response); }); return tcs.Task; } 几次,然后按照正确的顺序以正确的顺序得到正确的响应:

SendAsync

困扰我的那一行是调用private async Task Connected() { Console.WriteLine((await SendAsync(new EchoRequest() { Text = "Test 1" })).Message); Console.WriteLine((await SendAsync(new EchoRequest() { Text = "Test 2" })).Message); Console.WriteLine((await SendAsync(new EchoRequest() { Text = "Test 3" })).Message); 的那一行。这是我不希望因各种原因标记Connected的方法。

async

具体来说,读取protected override void StatusChanged(NetIncomingMessage message) { switch (message.SenderConnection.Status) { case NetConnectionStatus.Connected: _serverConnection = new ServerConnection(this, message.SenderConnection); (new Task(async () => { await Connected(); })).Start(); break; } } 的行对我来说感觉真的很“臭”,但这是我弄清楚Visual Studio停止向我发出警告的唯一方法。

我是否已正确包装(new Task(async () => { await Connected(); })).Start();以进行异步/等待,或者我在此处所做的任何事情都会导致我的问题进一步发生?我有更好的方式致电Send吗?

1 个答案:

答案 0 :(得分:3)

我认为;with sumA as ( select sum(tableA.value) value from tableA where tableA.data between '2016-01-21' and '2016-03-09' ), sumB as ( select sum(tableB.value) value from tableB where tableB.date2 between '2016-01-21' and '2016-03-09' ) select a.Value + b.Value from sumA, sumB; 是一个事件处理程序?因此,您需要StatusChanged

async void

编辑由于它不是事件处理程序,并且您有各种理由不对其进行标记protected override async void StatusChanged(NetIncomingMessage message) { //use await here } ,我可以提出的唯一建议是:使用async代替{ {1}},如果您不想更改方法的签名,它可能是最合适的解决方案。

Task.Run

new Task vs Task.Factory.StartNew

Task.Run vs Task.Factory.StartNew