3
我有這樣的方法:爲什麼我收到異常:阻塞操作被WSACancelBlockingCall調用中斷?
public DateTime GetNetworkTime()
{
DateTime networkDateTime = DateTime.Now;
try
{
IPAddress[] addresses = null;
//default Windows time server
const string ntpServer = "time.windows.com";
const string ntpServer1 = "time.nist.gov";
const string ntpServer2 = "time-nw.nist.gov";
const string ntpServer3 = "time-a.nist.gov";
const string ntpServer4 = "time-b.nist.gov";
List<string> ntpServersList = new List<string>();
ntpServersList.Add(ntpServer);
ntpServersList.Add(ntpServer1);
ntpServersList.Add(ntpServer2);
ntpServersList.Add(ntpServer3);
ntpServersList.Add(ntpServer4);
// NTP message size - 16 bytes of the digest (RFC 2030)
var ntpData = new byte[48];
//Setting the Leap Indicator, Version Number and Mode values
ntpData[0] = 0x1B; //LI = 0 (no warning), VN = 3 (IPv4 only), Mode = 3 (Client Mode)
for (int i = 0; i < ntpServersList.Count; i++)
{
addresses = Dns.GetHostEntry(ntpServersList[i]).AddressList;
if (addresses.Length > 0)
{
break;
}
}
//The UDP port number assigned to NTP is 123
var ipEndPoint = new IPEndPoint(addresses[0], 123);
//NTP uses UDP
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.Connect(ipEndPoint);
socket.Send(ntpData);
Thread th = new Thread(()=>
{
socket.Receive(ntpData);
flag.Set();
});
th.IsBackground = true;
th.Start();
//Block the current thread for 5 seconds
flag.WaitOne(5000, false);
socket.Close();
//Offset to get to the "Transmit Timestamp" field (time at which the reply
//departed the server for the client, in 64-bit timestamp format."
const byte serverReplyTime = 40;
//Get the seconds part
ulong intPart = BitConverter.ToUInt32(ntpData, serverReplyTime);
//Get the seconds fraction
ulong fractPart = BitConverter.ToUInt32(ntpData, serverReplyTime + 4);
//Convert From big-endian to little-endian
intPart = SwapEndianness(intPart);
fractPart = SwapEndianness(fractPart);
var milliseconds = (intPart * 1000) + ((fractPart * 1000)/0x100000000L);
//**UTC** time
networkDateTime = (new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc)).AddMilliseconds((long)milliseconds);
}
catch(Exception err)
{
MessageBox.Show("error" + err.ToString());
}
return networkDateTime.ToLocalTime();
}
在Form1的頂部我沒有:
AutoResetEvent flag;
在構造:
flag = new AutoResetEvent(false);
然後在GetNetworkTime上述方法()中的我改變的部分是:
Thread th = new Thread(()=>
{
socket.Receive(ntpData);
flag.Set();
});
th.IsBackground = true;
th.Start();
//Block the current thread for 5 seconds
flag.WaitOne(5000, false);
使用標誌和線程程序之前是杭/凍結,我也DEBUG>打破一切(暫停) 它停就行了:
socket.Receive(ntpData);
,所以我說這個標誌和線程的代碼。 現在運行我的程序我得到就行此異常時:
socket.Receive(ntpData);
SocketException 阻塞操作是通過調用中斷WSACancelBlockingCall
System.Net.Sockets.SocketException was unhandled
HResult=-2147467259
Message=A blocking operation was interrupted by a call to WSACancelBlockingCall
Source=System
ErrorCode=10004
NativeErrorCode=10004
StackTrace:
at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
at System.Net.Sockets.Socket.Receive(Byte[] buffer)
at TestDateTime.Form1.<>c__DisplayClass1.<GetNetworkTime>b__0() in d:\C-Sharp\TestDateTime\TestDateTime\TestDateTime\Form1.cs:line 125
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
當您嘗試「接收」時,您正在強制關閉套接字。結果令人驚訝嗎? – Jon