1

.DLL を介して一部のアクセス デバイスのサーバーとして機能する C# winforms アプリケーションがあります。

ユーザー アクセスは、入力を Web サービス (Web 参照として設定) に送信し、結果をデバイスに返すことによって決定されますが、タイムアウトの場合、アプリはすべてのデバイスを切断し、サーバーを停止し、バックグラウンド ワーカーを起動します。バックグラウンド ワーカーは Web サービスへの接続を再試行し、成功した場合はサーバーを再起動し、デバイスを再接続します。

これはすべて非常にうまく機能しますが、残念ながら、3 回目または 5 回目にバックグラウンド ワーカーが Web サービスに再接続しようとすると、「アプリケーションが 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);
            }
        }

補足として、それ以外の場合、Webサービスは魅力的に機能します。

4

1 に答える 1

0

例外ハンドラーで手動で 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();
于 2014-11-03T10:53:08.847 に答える