C# 异步TcpClient.Connect()如何使用它?

C# 异步TcpClient.Connect()如何使用它?,c#,asynchronous,tcp,tcpclient,C#,Asynchronous,Tcp,Tcpclient,目前我正在同步将客户端连接到服务器。 但是,服务器有时不可用,因此我认为使用异步会更好,这样我就可以收集并格式化以后要发送的数据。我发现我正在寻找的方法可能是 不幸的是,我对异步操作一无所知,所以这些参数让我感到奇怪。 例如:我必须单独使用IP和端口(即不使用IPEndPoint)有什么具体原因吗? 然而,更重要的问题是:AsyncCallback和Object,它们是什么? 我需要更改服务器上的任何内容吗? 我想我明白snyc或asnyc是本地选择,不会影响另一方,至少在兼容性方面是这样。 最

目前我正在同步将客户端连接到服务器。
但是,服务器有时不可用,因此我认为使用异步会更好,这样我就可以收集并格式化以后要发送的数据。我发现我正在寻找的方法可能是
不幸的是,我对异步操作一无所知,所以这些参数让我感到奇怪。
例如:我必须单独使用IP和端口(即不使用IPEndPoint)有什么具体原因吗?
然而,更重要的问题是:AsyncCallback和Object,它们是什么?
我需要更改服务器上的任何内容吗?
我想我明白snyc或asnyc是本地选择,不会影响另一方,至少在兼容性方面是这样。
最后:我阅读了关于asnyc的关键词,并等待:在哪里使用它们以及如何使用它们

这里有一个小的伪代码来演示我拥有什么和我想要什么

private static void send(string msg) {
    TcpClient cli = new TcpClient(localEP);
    bool loop = true;
    while(loop) {      //trying over and over till it works
        try {          //is bad practice and inefficient
            cli.Connect(remoteEP);
        } catch (Exception) {
            ;
        }
        if(cli.Connected)
            break;
    }
    var blah = doOtherThings(msg);
    useTheClient(blah);
}
现在我多么希望它能起作用

private static void send(string msg) {
    TcpClient cli = new TcpClient(localEP);
    cli.BeginConnect(remoteEP); //thread doesn't block here anymore + no exceptions
    var blah = doOtherThings(msg); //this now gets done while cli is connecting
    await(cli.connect == done) //point to wait for connection to be established
    useTheClient(blah);
}

您需要创建一个新的
AsyncCallback
,并将其设置为一个特定的void,一旦
TcpClient
完成与主机的连接,就可以执行某些操作。您可能还想通过检查
TcpClient.Connected的值来检查
TcpClient
连接是否成功

示例

下面的示例演示了在端口80上与google.com的异步
TcpClient
连接

static TcpClient cli = new TcpClient(); //Initialize a new TcpClient
static void Main(string[] args)
{
    send("Something");
    Console.ReadLine();
}
private static void doSomething(IAsyncResult result)
{
    if (cli.Connected) //Connected to host, do something
    {
        Console.WriteLine("Connected"); //Write 'Connected'
    }
    else
    {
        //Not connected, do something
    }
    Console.ReadLine(); //Wait for user input
}
private static void send(string msg)
{
    AsyncCallback callBack = new AsyncCallback(doSomething); //Set the callback to the doSomething void
    cli.BeginConnect("google.com", 80, callBack, cli); //Try to connect to Google on port 80
}
这里有一个更好的方法来做你在评论中描述的事情

System.Threading.Thread newThread = new System.Threading.Thread((System.Threading.ThreadStart)delegate {
//Do whatever you want in a new thread
    while (!cli.Connected)
    {
        //Do something
    }
});
newThread.Start(); //Start executing the code inside the thread
//This code will still run while the newThread is running
Console.ReadLine(); //Wait for user input
newThread.Abort(); //Stop the thread when the user inserts any thing

好的,这看起来比我以前发现的任何东西都简单。这意味着:“连接时,调用
回调
并传递
“已连接”
,直到代码被进一步执行。到目前为止我说的对吗?除了void类型之外,回调函数的设计是否有任何限制,比如只有一个参数是IAsyncResult?现在,我如何定义asnyc事件结束前我不想通过的点,即它必须连接的点,我不能再做任何其他事情了?@标记“是”,代码将在后台执行,而您的应用程序将正常运行。然后,当TcpClient完成连接或尝试连接时,它将运行回调void。然后,回调void通过检查
cli.Connected
值来检查TcpClient是否成功连接,很抱歉,我没有真正理解你的最后一个问题,你是什么意思?@Mark很好,您可以使用
System.Threading.Thread
启动新线程,并在不干扰主线程的情况下执行任何操作。我编辑了这篇文章以满足您的需要。最后一件事:当您调用beginconnect时,您传递了字符串“connected”:该字符串去了哪里?@标记这篇文章的上一版本中,我发现选中
TcpClient.connected
是一个更好的选择,因此我编辑了这篇文章。如果您想查看第一版的链接,请点击这里: