2009-12-15 75 views
2

我正在创建一个小游戏客户端,它将最终连接到服务器以收集有关可用游戏的信息,有多少玩家正在玩以及其他各种您可以想象它应该做的事情。使用C#连接/重试连接的最有效方法?

我的困难在于找到一种有效的方法来处理第一次加载时的连接/重试连接序列。

我想象我的客户将按照此过程中试图连接:

  1. 客户端应用程序执行
  2. 尝试建立连接
  3. 如果连接成功收集信息 - 如果不成功继续步骤4
  4. 显示一个新的对话框/窗体,提示用户连接正在尝试建立
  5. 循环直到连接建立

我一直在质疑我的方法试图按照这个顺序。我质疑这是否是正确/最有效的连接方式,以及为什么我在第4步中显示的表单不工作?

try 
{ 
    sock.Connect(authenServerEP); 
    // Once connected show our main client window 
    this.Show(); 
    // Create the LoginForm once a connection has been established and display 
    LoginForm loginForm = new LoginForm(); 
    loginForm.ShowDialog(); 
    if (false == loginForm.Visible) 
    { 
     loginForm.Dispose(); 
    } 
} 
catch (SocketException firstConnectException) 
{ 
    // Load retrying connection form 
    EstablishingConnectionForm establishingConnectionForm = new EstablishingConnectionForm();         
    establishingConnectionForm.Show(); 

    bool connected = false; 
    // Loop until we are connected 
    while (!connected) 
    { 
     try 
     { 
      sock.Connect(authenServerEP); 
      connected = true; 
      establishingConnectionForm.Dispose(); 
     } 
     catch (SocketException retryConnectException) 
     { 
      // Pass and retry connection 
     } 
    } 
} // end catch (SocketException firstConnectException) 

正如你可以看到我赶上当有连接到服务器(如服务器未运行)一个问题,即在引发SocketException。然后我继续尝试连续循环,直到建立连接。我不知道我是否应该这样做。有没有更好的方法来做到这一点?

另外,当我用Show()显示EstablishConnectionForm时,它看起来并不像所有的表单/工具初始化(初始化可能会引起误解)。表单上的标签只是以白色显示,而不是显示其文本。不仅如此,但似乎我不能选择窗体/对话框并实际移动它。它坐落在那里,带有“Thinking/Working”鼠标图标。现在我想这是因为我正在循环试图重新连接,并因此阻塞(我可能在阻塞方面是错误的?)。多线程能解决这个问题吗?如果是这样,我需要多线程?有没有更简单的方法来显示我的表单/对话框,并且能够在我仍然尝试重新连接的情况下与它进行交互(IE电影,并用它右上角的'X'来关闭它)?

谢谢你一堆。我非常感谢你阅读这篇文章,并感谢这个社区。 :D

回答

4

只是一个例子,下面我将处理catch中的任何继续逻辑,并在while循环内发生或继续。

安德鲁

while (!connected) 
{ 
    try 
    { 
     sock.Connect(authenServerEP); 
     connected = true; 
     establishingConnectionForm.Dispose(); 
    } 
    catch (SocketException retryConnectException) 
    { 
     //Optional - add some wait time may be 5 seconds i.e. "trying again in 5 seconds" 
     //System.Threading.Thread.Sleep(5000); 
     //Here check the number of attempts and if exceeded: 
     if(numberOfTimes == 5) 
     { 
      break; 
     } 
     else 
     { 
      numberOfTimes++; 
      continue; 
     } 
    } 
} 
+1

我第二这个答案。它实际上遵循所谓的断路器模式。尝试某种情况直到出现某种情况或达到阈值。处理无法控制的外部连接时非常方便。 – 2009-12-15 12:41:40

+0

这工作很好。我感谢您的帮助。我留下来处理的一件事情是,当我捕捉到SocketException时,我无法与它交互,似乎在启动我的EstablishConnectionForm时。它总是显示思维图标,永远不会让我选择它并移动它。现在我想这是因为我正在循环试图重新连接,并因此阻塞(我可能在阻塞方面是错误的?)。这是一个难题吗?(IE所有的连接都应该在线程上完成,所以这个连接不会阻塞 - 如果阻塞的话) – Chris 2009-12-15 19:24:20

+0

是的while循环会导致线程阻塞。在单独的线程上踢出它并启动事件以通知更新状态的监听实体! – 2009-12-16 01:26:30