異步,及用tcpclient的異步連接方式,設置連接超時


如題

先說異步連接的超時:

原理:異步連接,獲取狀態。阻止主進程等待異步進程返回。指定異步進程超時時間,這段時間內,如果異步連接沒有返回,則以未完成狀態返回,主進程繼續。

根據對獲取到的狀態的識別,來判斷是超時還是收到回應而使進程繼續。再分別處理。

代碼:

static void Main(string[] args)
        {
            for (int i = 20; i <= 25; i++)
            {
                TcpClient tcp = new TcpClient();
                IAsyncResult async = tcp.BeginConnect(IPAddress.Parse("120.27.234.XXX"), i, null, null);
                async.AsyncWaitHandle.WaitOne(1000);
                if (async.IsCompleted)
                {
                    Console.WriteLine($"{i} is open.");
                }
                else
                {
                    Console.WriteLine($"{i} is closed."); ;
                }
                tcp.Close();
            }
            Console.WriteLine("ok");
            Console.ReadKey();
        }

 關於異步:

除了上面的類對象提供異步方法以外,所有的委托都可以異步執行。例如:

static void Main(string[] args)
        {
            Action<string> action = sayhi;
            Func<int,int,int> func = add;
            IAsyncResult r1,r2;

            r1 = action.BeginInvoke("張三",null,null);
            r1.AsyncWaitHandle.WaitOne(1000);
            if (r1.IsCompleted)
            {
                Console.WriteLine($"ok1");
            }
            else
            {
                Console.WriteLine($"no1"); ;
            }

            r2 =func.BeginInvoke(1, 2, (g)=>myCallBack("王子","公主"), null);
            r2.AsyncWaitHandle.WaitOne(1000);
            if (r2.IsCompleted)
            {
                Console.WriteLine($"{func.EndInvoke(r2)}ok2");
            }
            else
            {
                Console.WriteLine($"no2"); ;
            }
            Console.ReadKey();
        }
        static int add(int x,int y)
        {
            return x + y;
        }
        static void sayhi(string x)
        {
            Console.WriteLine($"Hello,{x}!");
        }
        static void myCallBack(string x,string y)
        {
            Console.WriteLine($"{x}和{y}終於幸福得生活在了一起");
        }

結果:

 

 

如上例:

action和function委托都可以異步。注意func委托的返回值需要特別讀一下。

 

回調方法可以用“new AsyncCallback(方法名)”來聲明,也可以用lamda表達式。

用lamda表達式的時候,可以鑽漏洞輸入任意參數,見例子。

注意:寫在拉姆達表達式里面的參數是在方法運行的時候加載,而不是在方法初始化的時候加載。如果是變量就要小心了。

對於正常的回調(如Task回調),如果需要在一開始確定參數的值,需要用object對象state顯式指定。

而對於委托的begininvoke方法,里面的回調參數,是IAsyncResult類型。需要用它的“AsyncState”參數獲取傳入的object類型的內容(這一點跟代碼提示的內容不一樣)。也可以用拉姆達表達式去寫,如:

myaction.BeginInvoke(o=>MessageBox.Show(this,o.AsyncState.ToString()), "ok");

回調方法也可以為null。

 

回調方法必須帶一個object參數。可以為null。

當然,委托也可以同步調用,此處略。




我覺得如果沒有控制要求,委托異步就很好了。但從參數傳遞的復雜度來看,微軟似乎並不推薦這種用法。
有控制要求的,可以試試task,見另一篇文章。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM