Вызов Webservice приводит к ошибке WSAStartUp после 3 успешных вызовов
У меня есть приложение C# winforms, которое функционирует как сервер для некоторых устройств доступа через.DLL.
Доступ пользователя определяется отправкой входных данных веб-службе (настроенной как веб-ссылка) и возвратом результатов на устройства, однако в случае тайм-аута приложение отключает все устройства, останавливает сервер и запускает фонового работника. Фоновый работник повторяет соединение с веб-сервисом и, если это удается, снова запускает сервер и повторно подключает устройства.
Это все работает очень хорошо, но, к сожалению, в третий, четвертый или пятый раз фоновый работник пытается повторно подключиться к веб-сервису, соединение не устанавливается с исключением: "Приложение не вызвало WSAStartup, или произошел сбой WSAStartup". каждая последующая попытка приводит к симиларной ошибке.
Вот источник для фонового работника, его очень простой код:
private void backgroundWorkerStopServer_DoWork(object sender, DoWorkEventArgs e)
{
System.Threading.Thread.Sleep(2000);
stopServer();
NewDoorCheck.Doorcheck ndoorcheck = new NewDoorCheck.Doorcheck();
ndoorcheck.Timeout = 15000;
bool disconnected = true;
while (disconnected)
{
try
{
ndoorcheck.WebserviceIsUp();
UpdateLog("Connected web");
disconnected = false;
startServer();
}
catch (Exception ex)
{
UpdateLog(ex.Message);
UpdateLog(ex.StackTrace);
UpdateLog("Still Down");
System.Threading.Thread.Sleep(60000);
}
}
Как примечание, веб-сервис работает как шарм в противном случае.
1 ответ
Я решил эту проблему, вызвав WSAstartup вручную в обработчике исключений и повторив попытку.
Импорт Winsock
class WSAinterop
{
[StructLayout(LayoutKind.Sequential)]
internal struct WSAData
{
public short wVersion;
public short wHighVersion;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 257)]
public string szDescription;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 129)]
public string szSystemStatus;
public short iMaxSockets;
public short iMaxUdpDg;
public int lpVendorInfo;
}
[DllImport("wsock32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
internal static extern int WSAStartup(
[In] short wVersionRequested,
[Out] out WSAData lpWSAData
);
[DllImport("wsock32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
internal static extern int WSACleanup();
private const int IP_SUCCESS = 0;
private const short VERSION = 2;
public static bool SocketInitialize()
{
WSAData d;
return WSAStartup(VERSION, out d) == IP_SUCCESS;
}
/// <summary>
/// The main entry point for the application.
/// </summary>
}
И просто используйте метод SocketInitialize().
bool startup = WSAinterop.SocketInitialize();