Вызов 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();
Другие вопросы по тегам