我不知道如何处理 SocketException 以满足我的需要

Posted

技术标签:

【中文标题】我不知道如何处理 SocketException 以满足我的需要【英文标题】:I do not know how to handle SocketException to suit my needs 【发布时间】:2015-03-21 04:40:05 【问题描述】:

简介及相关资料:

我是一名缺乏经验的 C# 开发人员,继承了同事的项目并负责修复某些错误。

其中一项任务是在 Internet 连接不可用时将应用程序切换到离线模式。我的同事使用OpenNetCF library 帮助他处理应用程序的 FTP 连接部分,这让我的工作变得更加困难。

问题在于“登录”形式。这是用户看到的第一件事,这个表单会自动尝试连接到服务器。如果没有可用的连接,它只是处于空闲状态,显示消息“正在连接...”。

问题:

如果连接不可用,我的任务是切换到离线模式。

我为解决这个问题所做的努力:

为了进一步解释,我觉得最好为登录表单的onLoad 事件提供代码:

// class fields:
delegate void StringDelegate(string value);
private FTP m_ftp;

private void dlgLoading_Load(object sender, EventArgs e)

    m_ftp = new FTP(address);
    m_ftp.ResponseReceived += new
        FTPResponseHandler(m_ftp_ResponseReceived);
    // m_ftp_Connected processes files in a certain way
    m_ftp.Connected += new FTPConnectedHandler(m_ftp_Connected);
    m_ftp.BeginConnect(username, password);
    // sets label's text to inform the user it is connecting
    lblText.Text += "Connecting...   ";

通过代码调试,我发现在另一个似乎属于OpenNETCF库的文件中抛出了异常SocketException。它的名字是FTP.cs,函数ConnectThread 在尝试连接时会抛出它。 ConnectThread 在上述代码中被m_ftp.BeginConnect 调用。

这很好,因为我没有调整模拟器来连接互联网。

在 JAVA 中,函数可以抛出异常。

通过阅读 C# 书籍/教程,在 Internet 和这里搜索,我发现这在 C# 中是做不到的。

但是,通过进一步搜索,我了解到在 C# 异常中未处理时会“冒泡”。

我得出的结论是,这可能是基于this 线程的良好编程实践(如果您无法处理异常,则“冒泡”异常)。

因此,我决定将异常从库中的方法一直“冒泡”到我的登录表单中的代码。然后我可以抓住它,并从那里以离线模式继续。

我已经从库/我的代码中的相关方法中删除了try/catch块,并将上面的代码更改为:

// class fields:
delegate void StringDelegate(string value);
private FTP m_ftp;

private void dlgLoading_Load(object sender, EventArgs e)

    try
    
        m_ftp = new FTP(address);
        m_ftp.ResponseReceived += new
            FTPResponseHandler(m_ftp_ResponseReceived);
        // m_ftp_Connected processes files in a certain way
        m_ftp.Connected += new FTPConnectedHandler(m_ftp_Connected);
        m_ftp.BeginConnect(username, password);
        // sets label's text to inform the user it is connecting
        lblText.Text += "Connecting...   ";
    
    catch( Exception ex )
    
        MessageBox.Show( ex.Message );
        // i thought of adding a check at this place
        // if exception is SocketException 
        // so I can launch "offline code" here
    

我希望在那里捕获异常,但我的程序终止了。我不确定,但这让我认为异常不会在任何地方得到处理。

问题:

在这种情况下,如何正确“冒泡”这种类型的异常? 我的方法有效吗(我提醒您我非常缺乏经验)?有比我的方法更好的解决方案吗?

由于缺乏经验,如果我遗漏了重要信息,我深表歉意。请发表评论,我会尽快编辑我的帖子。

【问题讨论】:

你可以有多个 catch 块。所以尝试catch(SocketException)//处理套接字错误catch(Exception)\\处理其他错误 @zaf:我可能是错的,但是在网上搜索后,我发现m_ftp.BeginConnect(username, password);调用启动了单独的线程。正是在这个线程中发生了异常。遗憾的是,按照您的指示修改代码并没有改变任何事情。似乎在删除 try/catch 块后,异常在线程中冒泡,从未到达我的表单,从而终止了应用程序。再说一次,我可能错了,我很缺乏经验,但这是我的逻辑...... 对不起,我错过了 BeginXXX 部分。无论如何,我不熟悉您正在使用的库,但通常使用 BeginXXX 的 .net 异步方法具有异步回调参数。在此回调中,您可以尝试并捕获错误。尝试查看您正在使用的 BeginConnect 方法是否过载。要将异常“冒泡”到 UI 线程,您可以使用 SynchronizationContext。 @zaf:我不熟悉你正在使用的库我也不熟悉,它是由我继承该项目的同事使用的 :) 通常使用 BeginXXX 的 .net 异步方法有一个异步回调参数。在此回调中,您可以尝试并捕获错误。尝试查看您正在使用的 BeginConnect 方法是否过载。要将异常“冒泡”到 UI 线程,您可以使用 SynchronizationContext。 目前有很多有用的信息需要处理,我将在线搜索,看看会发生什么。感谢您为我指明正确的方向。 【参考方案1】:

异步风格的方法(例如 BeginXxx)只能在回调/事件中报告错误,因为错误仅在调用返回后发生。处理回调中的错误。它将被 EndXxx 方法抛出。

对于每个 BeginXxx 调用,必须有一个对应的 EndXxx 调用,通常在回调中进行。

这是 APM 模式。

【讨论】:

感谢您的回答,非常感谢。作为这一切的新手,在我正式接受您的回答之前,我可能需要一些时间来实施您的解决方案,所以请耐心等待。最好的问候。 如果您想要一个更简单的模型,如果您的库支持,请使用 await。这是迄今为止结合 UI 运行异步工作的最简单方法。没有等待就不要使用异步 IO。使用 Task.Run 启动一个任务,它会完成所有工作。不再需要事件或回调。

以上是关于我不知道如何处理 SocketException 以满足我的需要的主要内容,如果未能解决你的问题,请参考以下文章

我不知道如何处理不同的错误

git status 给了我一些令人困惑的 iOS 配置文件,我不知道如何处理 [重复]

制作决策树时如何处理数据

我如何处理 .FirstOrDefault 方法?

不知道如何处理大型数据库

如何处理点击推送通知ios