通过异步服务器通讯/等待? [英] Server communication via async/await?
问题描述
我要创建的Socket消息通过异步通过TAP发送/等待。
I want to create Socket message sending via TAP via async/await.
After reading this answer and this one - I decided to create a fully working sample :
那么,什么有我尝试:
我从<一的TAP extenstion方法href=\"http://stackoverflow.com/questions/21539766/receive-correct-amount-of-data-tcp/21540278#21540278\">here (一切OK了),我就在控制台CMD测试:
I took the TAP extenstion methods from here (all ok) : and I test it in console cmd :
Reciever code
public static class SocketExtensions
{
public static Task<int> ReceiveTaskAsync(this Socket socket, byte[] buffer, int offset, int count)
{
return Task.Factory.FromAsync<int>(
socket.BeginReceive(buffer, offset, count, SocketFlags.None, null, socket),
socket.EndReceive);
}
public static async Task<byte[]> ReceiveExactTaskAsync(this Socket socket, int len)
{
byte[] buf = new byte[len];
int totalRead = 0;
do{
int read = await ReceiveTaskAsync(socket, buf, totalRead, buf.Length - totalRead);
if (read <= 0) throw new SocketException();
totalRead += read;
}while (totalRead != buf.Length);
return buf;
}
public static Task ConnectTaskAsync(this Socket socket, string host, int port)
{
return Task.Factory.FromAsync(
socket.BeginConnect(host, port, null, null),
socket.EndConnect);
}
public static Task SendTaskAsync(this Socket socket, byte[] buffer)
{
return Task.Factory.FromAsync<int>(
socket.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, null, socket),
socket.EndSend);
}
}
static void Main()
{
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
s.ConnectTaskAsync("127.0.0.1", 443);
var buf1 = s.ReceiveExactTaskAsync(100); //read exactly 100 bytes
Console.Write(Encoding.UTF8.GetString(buf1.Result));
var buf2 = s.ReceiveExactTaskAsync(100); //read exactly 100 bytes
Console.Write(Encoding.UTF8.GetString(buf2.Result));
Console.ReadLine();
}
发件人code:
// use same extension method class like above ....^
void Main()
{
Socket s = new Socket(SocketType.Stream , ProtocolType.Tcp);
s.ConnectTaskAsync( "127.0.0.1" , 443);
s.SendTaskAsync(Encoding.UTF8.GetBytes("hello"));
s.Close();
Console.ReadLine();
}
的注意我删除了异步
从主要因为即时通讯在控制台测试。的
notice I removed the async
from main since im testing it in console.
问题,
根据上述环线,code应该工作
According to link above , the code should work
不过我越来越也不例外,它只是挂在该行:
However I'm getting no exception and it's just hangs on that line :
Console.Write(Encoding.UTF8.GetString(buf1.Result));
的(首先我运行接收器,然后我跑发送)的
我是什么失踪?
推荐答案
这个问题来自于请注意我删除了异步从主要因为即时通讯在控制台测试。的。
您需要等待的操作做下一步之前完成。在code你为榜样暂停使用每个等待
的操作来完成,您的code只是去直接通过。
You need to wait for the operation to complete before doing the next step. The code you used as an example pauses at each await
for the operation to complete, your code just goes straight through.
您可以通过将解决这个问题一个 .Wait()
,将有一个每个操作的await $ C $之后C>或通过
Task.Run运行的线程池线程内这个函数(
,然而的我觉得这是更好地知道什么时候你应该使用异步当你不应该。
You may be able to fix this by putting a .Wait()
after each operation that would have had a await
or by running this function inside a threadpool thread via Task.Run(
, however I think it is better to know when you should use async and when you should not.
异步时,应使用有其他的工作,你可以有螺纹做,非常普遍,其他工作将东西像一个WinForms项目处理UI消息或接受新的连接一个ASP.NET网站。在一个控制台应用程序有程序可以做,而等待没有其他的工作,所以在这种情况下,它会更适合使用的功能同步版本而不是。
Async should be used when you have other work you could have the thread be doing, very commonly that "other work" will be things like processing UI messages on a WinForms project or accepting new connections on a ASP.NET site. In a console application there is no other work your program could be doing while it waits, so in that situation it would be more appropriate to use the synchronous version of the functions instead.
P.S。您提出的意见后,我贴的这就是为什么我删除了异步等待并用Task.result 的,只是让你知道永远的曾经的 1 结合code,使用等待
和code,阻止同步大赛(通过使用像 Task.Result $ C $的东西C>或
Task.Wait()
,你可能会导致您的code死锁和停止工作!
P.S. You made the comment after I posted "that's why I remove the async awaits and used Task.result", just so you know never ever1 combine code that uses await
and code that blocks the synchronization contest (by using things like Task.Result
or Task.Wait()
, you will likely cause your code to deadlock and stop functioning!
这是不是你的当前例如问题,因为控制台应用程序没有同步的情况下,但如果你复制粘贴此code的东西,没有你可以很容易地锁定您的程序。
It is not a issue for your current example because console applications do not have a synchronization context, but if you copied and pasted this code to something that did you could easily lock up your program.
1:好吧,你可以结合等待
和阻断code,但也有需要遵循的规则,但如果你知道足够的争议我你知道我的意思,足以安全地做到这一点。如果你不知道如何安全地做它只是避免做
1: Ok, you could combine await
and blocking code but there are rules you need to follow, but if you know enough to dispute my what I am saying you know enough to safely do it. If you don't know how to safely do it just avoid doing it
这篇关于通过异步服务器通讯/等待?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!