设置我的套接字进行连接时,我将方法包装在try-catch块中..
如果引发套接字异常,我创建一个新线程..休眠15秒..然后再次调用connect方法,但这次是从另一个线程。我这样做主要是为了睡眠方法(避免使用计时器重新连接)而不挂断主线程。
无论如何..在尝试连接时,我使用一个名为Write()的方法将状态写入文本框,该方法只是将文本附加到当前文本中,然后使用\ n ...
因为在连接失败时我创建了一个单独的线程来调用connect方法(它可以修改表单上的控件),我在方法调用上使用invoke是对的吗?
这是我的代码
private void Connect()
{
try
{
Write("Connecting...");
_ClientSocket.Connect(new IPEndPoint(IPAddress.Loopback, 2500));
Connected = true;
Write("Connected.");
_ClientSocket.BeginReceive(Buffer, 0, Buffer.Length, 0, new AsyncCallback(RecieveCallBack), null);
}
catch (SocketException ex)
{
Write("Connection Failed. Trying again in 15 Seconds...");
Connected = false;
new Thread(delegate()
{
Thread.Sleep(15000);
Invoke((MethodInvoker)delegate
{
this.Connect();
});
}).Start();
}
catch (Exception ex)
{
}
}
我只是想确保我以正确的方式这样做
答案 0 :(得分:1)
在提供的方案中,它使用new Thread
,Thread.Sleep
和Invoke
只是为了在15秒内安排在UI线程上完成一些工作。它会工作,但......效率很低(线程昂贵)。坦率地说,应该使用一个计时器 - 或者可能是Task.Delay
在4.5上(实际上它只是包装一个计时器)。
答案 1 :(得分:1)
您最初可以假设连接不会成功,而不是创建连接线程。这将需要轮询计时器重新连接。奖励:您可以控制计时器(虽然您无法对匿名线程执行任何操作),您可以将其用于其他需要轮询的任务(重新发送数据,第一次尝试时未发送,如果更改套接字设置则断开连接后排队连接等)
此轮询计时器可以是普通的UI计时器(如果是winforms,则为Timer),那么您不需要任何调用。如果你这样做,那么请确保没有阻塞操作(例如,发送数据并等待答案)。
否则,您可以使用this扩展方法来始终在UI线程中运行它们
public static void InvokeIfRequired(this Control control, MethodInvoker action)
{
if (control.InvokeRequired)
control.Invoke(action);
else
action();
}
在您的情况下,您需要像这样致电Write
someUIControl.InvokeIfRequired(() => Write(...));
或者只需像这样制作Write
方法
void Write(...)
{
if(someUIControl.InvokeRequired)
someUIControl.Invoke((delegate)() => Write(...));
else
{
... job here
}
}