C# 如何检查I';我接通了吗?
全部,, 我正在编写一个应用程序,它需要与服务器建立异步阻塞连接。 我有一个带有按钮的GUI表单和一个类,该类使用BeginConnect/EndConnect对执行连接。 实现遵循MSDN示例 然而,在回调方法中抛出异常。这是我试图避免的。 我想要做的是检查连接是否已经建立,如果没有连接,在我的GUI表单上以文本的形式显示相应的错误 我试图检查BeginConnect()的返回值,但它在调用静态方法之前返回。 我试图在建立连接时重新抛出异常并捕获它(按钮单击事件),但它不起作用。未捕获异常 如何检查是否已建立连接 我可能可以将文本控件传递给connection类,并在捕获异常时将文本设置为错误,但是还有其他方法吗 多谢各位 [编辑]C# 如何检查I';我接通了吗?,c#,sockets,asynchronous,C#,Sockets,Asynchronous,全部,, 我正在编写一个应用程序,它需要与服务器建立异步阻塞连接。 我有一个带有按钮的GUI表单和一个类,该类使用BeginConnect/EndConnect对执行连接。 实现遵循MSDN示例 然而,在回调方法中抛出异常。这是我试图避免的。 我想要做的是检查连接是否已经建立,如果没有连接,在我的GUI表单上以文本的形式显示相应的错误 我试图检查BeginConnect()的返回值,但它在调用静态方法之前返回。 我试图在建立连接时重新抛出异常并捕获它(按钮单击事件),但它不起作用。未捕获异常 如
class InternetConnector
{
public void ConnectToHost()
{
IPEndPoint ip = new IPEndPoint(IPAddress.Parse(connector_host), connector_port);
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
client.Blocking = true;
client.BeginConnect(ip, new AsyncCallback(ConnectCallback), client);
}
private static void ConnectCallback(IAsyncResult ar)
{
try
{
Socket sock = (Socket)ar.AsyncState;
sock.EndConnect(ar);
connectDone.Set();
Connected = true;
}
catch (Exception e)
{
throw (e);
}
}
}
public partial class Form1 : Form
{
private bool isRunning = false;
private InternetConnector client = new InternetConnector();
private void startStop_Click(object sender, EventArgs e)
{
try
{
if (!isRunning || !InternetConnector.Connected)
{
if (!InternetConnector.Connected)
{
client.SetAddress(ipAddress.Text);
client.SetPort(Convert.ToInt32(connectionport.Text));
client.ConnectToHost();
status.Text = "Signals Receiver: Connected";
status.ForeColor = Color.Green;
startStop.Text = "Stop";
isRunning = true;
}
else
{
startStop.Text = "Start";
client.DisconnectFromHost();
isRunning = false;
}
}
}
catch(Exception ex)
{
status.Text = "Socket Error: " + ex.Message;
}
}
}
如果在回调中使用“throw(e);”,则在click listener中不会捕获捕获块异常。
但回调中需要try/catch,因为错误连接正在引发异常而不返回错误。有属性。有属性。在windows中
如果未发生错误,connect返回零。否则,它将返回SOCKET_ERROR,并且可以通过调用
WSAGetLastError
在窗户里
如果未发生错误,connect返回零。否则,它将返回SOCKET_ERROR,并且可以通过调用
WSAGetLastError
因为您使用的是异步BeginConnect,所以回调几乎不会在与单击处理程序相同的线程上发生,因此单击处理程序无法捕获异常 如果需要从异步回调设置UI元素的状态,通常需要在创建UI的同一线程上执行委托 从控件派生的任何UI元素都有一些方法可以帮助您完成此操作(
invokererequired
和BeginInvoke
)。我修改了你的样品来帮助说明这一点
基本上,您可以传入一个动作委托,如果该动作委托发生在异步连接回调中,则该动作委托将被异常调用。然后,此错误处理委托可以根据异步连接回调期间引发的异常执行所有工作,以设置UI状态
class InternetConnector
{
private struct ConnectionData
{
public Action<Exception> ErrorHandler { get; set; }
public Socket Socket { get; set; }
}
public void ConnectToHost(Action<Exception> errorHandler)
{
IPEndPoint ip = new IPEndPoint(IPAddress.Parse(connector_host), connector_port);
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
var connectionData = new ConnectionData { ErrorHandler = errorHandler, Socket = client };
client.Blocking = true;
client.BeginConnect(ip, new AsyncCallback(ConnectCallback), connectionData);
}
private static void ConnectCallback(IAsyncResult ar)
{
ConnectionData connectionData = new ConnectionData();
try
{
connectionData = (ConnectionData)ar.AsyncState;
connectionData.Socket.EndConnect(ar);
connectDone.Set();
Connected = true;
}
catch (Exception e)
{
if (connectionData.ErrorHandler != null)
connectionData.ErrorHandler(e);
}
}
}
public partial class Form1 : Form
{
private bool isRunning = false;
private InternetConnector client = new InternetConnector();
private void AsyncErrorHandler(Exception e)
{
if (status.InvokeRequired)
{
// queue a call to ourself on control's UI thread and immediately return
status.BeginInvoke(new Action(()=>AsyncErrorHandler(e)));
return;
}
// we are on the right thread to set the status text
status.Text = "Async Error: " + ex.Message;
}
private void startStop_Click(object sender, EventArgs e)
{
try
{
if (!isRunning || !InternetConnector.Connected)
{
if (!InternetConnector.Connected)
{
client.SetAddress(ipAddress.Text);
client.SetPort(Convert.ToInt32(connectionport.Text));
// connect, pass in the method to use for error reporting
client.ConnectToHost(AsyncErrorHandler);
status.Text = "Signals Receiver: Connected";
status.ForeColor = Color.Green;
startStop.Text = "Stop";
isRunning = true;
}
else
{
startStop.Text = "Start";
client.DisconnectFromHost();
isRunning = false;
}
}
}
catch(Exception ex)
{
status.Text = "Socket Error: " + ex.Message;
}
}
}
因为我们需要传入错误处理委托,所以我们必须创建一个结构(称为ConnectionData)来保存我们需要在异步连接回调中访问的所有状态(套接字和错误处理程序)
class InternetConnector
{
private struct ConnectionData
{
public Action<Exception> ErrorHandler { get; set; }
public Socket Socket { get; set; }
}
public void ConnectToHost(Action<Exception> errorHandler)
{
IPEndPoint ip = new IPEndPoint(IPAddress.Parse(connector_host), connector_port);
client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
var connectionData = new ConnectionData { ErrorHandler = errorHandler, Socket = client };
client.Blocking = true;
client.BeginConnect(ip, new AsyncCallback(ConnectCallback), connectionData);
}
private static void ConnectCallback(IAsyncResult ar)
{
ConnectionData connectionData = new ConnectionData();
try
{
connectionData = (ConnectionData)ar.AsyncState;
connectionData.Socket.EndConnect(ar);
connectDone.Set();
Connected = true;
}
catch (Exception e)
{
if (connectionData.ErrorHandler != null)
connectionData.ErrorHandler(e);
}
}
}
public partial class Form1 : Form
{
private bool isRunning = false;
private InternetConnector client = new InternetConnector();
private void AsyncErrorHandler(Exception e)
{
if (status.InvokeRequired)
{
// queue a call to ourself on control's UI thread and immediately return
status.BeginInvoke(new Action(()=>AsyncErrorHandler(e)));
return;
}
// we are on the right thread to set the status text
status.Text = "Async Error: " + ex.Message;
}
private void startStop_Click(object sender, EventArgs e)
{
try
{
if (!isRunning || !InternetConnector.Connected)
{
if (!InternetConnector.Connected)
{
client.SetAddress(ipAddress.Text);
client.SetPort(Convert.ToInt32(connectionport.Text));
// connect, pass in the method to use for error reporting
client.ConnectToHost(AsyncErrorHandler);
status.Text = "Signals Receiver: Connected";
status.ForeColor = Color.Green;
startStop.Text = "Stop";
isRunning = true;
}
else
{
startStop.Text = "Start";
client.DisconnectFromHost();
isRunning = false;
}
}
}
catch(Exception ex)
{
status.Text = "Socket Error: " + ex.Message;
}
}
}
class互联网连接器
{
私有结构连接数据
{
公共操作错误处理程序{get;set;}
公共套接字{get;set;}
}
public void ConnectToHost(操作错误处理程序)
{
IPEndPoint ip=新IPEndPoint(IPAddress.Parse(连接器\主机)、连接器\端口);
client=newsocket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
var connectionData=new connectionData{ErrorHandler=ErrorHandler,Socket=client};
client.Blocking=true;
BeginConnect(ip,新的异步回调(ConnectCallback),connectionData);
}
专用静态无效连接回调(IAsyncResult ar)
{
ConnectionData ConnectionData=新的ConnectionData();
尝试
{
connectionData=(connectionData)ar.AsyncState;
连接数据。插座。终端连接(ar);
connectDone.Set();
连接=真;
}
捕获(例外e)
{
if(connectionData.ErrorHandler!=null)
connectionData.ErrorHandler(e);
}
}
}
公共部分类Form1:Form
{
私有布尔值正在运行=false;
专用InternetConnector客户端=新的InternetConnector();
私有void AsyncErrorHandler(异常e)
{
if(status.invokererequired)
{
//在控件的UI线程上排队调用自己,并立即返回
status.BeginInvoke(新操作(()=>AsyncErrorHandler(e));
回来
}
//我们在正确的线程上设置状态文本
status.Text=“异步错误:”+ex.消息;
}
私有无效开始停止单击(对象发送者,事件参数e)
{
尝试
{
如果(!isRunning | |!InternetConnector.Connected)
{
如果(!InternetConnector.Connected)
{
client.SetAddress(ipAddress.Text);
SetPort(Convert.ToInt32(connectionport.Text));
//连接,传入用于错误报告的方法
ConnectToHost(AsyncErrorHandler);
status.Text=“信号接收器:已连接”;
status.ForeColor=Color.Green;
startStop.Text=“停止”;
isRunning=true;
}
其他的
{
startStop.Text=“开始”;
client.DisconnectFromHost();
isRunning=false;
}
}
}
捕获(例外情况除外)
{
status.Text=“套接字错误:”+ex.消息;
}
}
}
因为您使用的是异步BeginConnect,回调几乎不会在与单击处理程序相同的线程上发生,因此单击处理程序无法捕获异常
如果你需要设置