我不知道如何处理SocketException以满足我的需求 [英] I do not know how to handle SocketException to suit my needs

查看:53
本文介绍了我不知道如何处理SocketException以满足我的需求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

介绍及相关信息:



我是一位缺乏经验的C#开发人员,继承了同事的项目(C# ,.NET 3.5,Windows Mobile 6.5),并负责修复某些错误。



其中一项任务是在互联网连接不可用时将应用程序切换到离线模式。我的同事使用 OpenNetCF库来帮助他处理应用程序的FTP连接部分,这对我来说更难。



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



问题:



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



我努力解决这个问题:



如需进一步说明,我觉得最好为登录提供代码 - form的 onLoad 事件:

INTRODUCTION AND RELEVANT INFORMATION:

I am an inexperienced C# developer that inherited colleague's project ( C#, .NET 3.5, Windows Mobile 6.5) and was tasked to fix certain bugs.

One of the tasks was to switch application to offline mode if Internet connection is unavailable. My colleague used OpenNetCF library to help him with the FTP connection part of the application, which makes things harder for me.

The problem lies in "login" form. This is the first thing user sees, and this form tries automatically to connect to server. If no connection is available, it simply stands idle, showing message "Connecting...".

PROBLEM:

My task is to switch to offline mode if connection is unavailable.

MY EFFORTS TO SOLVE THIS:

For further explanation, I feel it would be best to provide code for the login-form's onLoad event:

// 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...   ";
}





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



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



JAVA ,函数可以抛出异常。



通过C#书籍/教程阅读,通过互联网搜索,在这里,我发现这不能在C#中完成。



然而,进一步搜索,我已经了解到,在C#例外情况下冒泡时没有处理。



我已经得出结论,这可能是一个很好的编程习惯(如果你不能处理它就冒泡异常)基于这个 [ ^ ]线程,是一个非常好的冒泡的例子。 />


因此,我决定将库中方法的异常冒泡到我登录表单中的代码。然后我就能抓住它,并在离线模式下从那里继续。



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



Debugging through code, I have found out that an exception SocketException has been thrown in another file that seems to belong to the OpenNETCF library. It's name is FTP.cs and the function ConnectThread throws it when trying to connect. ConnectThread is called by m_ftp.BeginConnect in the above code.

This is perfectly fine, because I haven't adjusted emulator to have Internet connection.

In JAVA, function can throw an exception.

Reading through C# books/tutorials, searching through Internet and here, I have found out that this can not be done in C#.

However, searching further, I have learned that in C# exceptions "bubble up" when not handled.

I have concluded that this might be good programming practice ( to "bubble up" the exception if you can't handle it ) based on this[^] thread.

Therefore, I have decided to "bubble up" the exception from the method in the library all the way to the code in my login-form. Then I could catch it, and continue from there in offline mode.

I have removed try/catch block from the relevant methods in the library/my code, and changed the above code to this:

// 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
    }
}





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



问题:



*在这种情况下,如何正确地冒泡这种类型的异常?



*我的方法是否有效(我提醒你我很缺乏经验)?有没有比我的方法更好的解决方案?



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

推荐答案





我刚看了一下 http://ftp.codeplex.com/SourceControl/latest#FTP .cs [ ^ ]和ConnectThread方法 - 如果它抛出异常它没有设置连接标志。



我想到了一些解决方案:





*尝试等待连接标志(通过调用FTP的CheckConnect方法)在某些超时时变为真(如果超时则假定连接失败) - 涉及某种轮询...不太好。

*更好:创建一些ConnectionErrorOccured事件并在ConnectThread方法内的异常时引发它,然后在表单中侦听事件(传递所需的异常信息以及您的事件作为事件数据)

*如果您在没有Internet连接之前知道,请避免代码运行(如果在CE上这么容易检查,那么就不要了...) - 不要解决其他连接问题...



所以我认为第二种解决方案是最好的....



只是我的2c



好​​运你的错误 - 修复...



亲切的问候

Johannes
Hi,

I just had a quick look at http://ftp.codeplex.com/SourceControl/latest#FTP.cs[^] and the ConnectThread method - if it throws the exception it doesn't set the connected flag.

Some Solutions come to my mind:


*Try to wait for the connected flag (by calling FTP's CheckConnect method) to become true with some timeout (if timeout exceeded you assume connecting failed) - involves some kind of polling... not so good.
*Better: create some "ConnectionErrorOccured" Event and raise it on exception inside the ConnectThread method, then listen for the Event in your Form (pass needed exception Information along with your Event as Event data)
*Avoid the code running if you "know" before that you have no Internet Connection (not shure if this is so easy to check on CE...) - doesn't solve other connection Problems...

So I think the second solution would be best....

Just my 2c

Good Luck with your bug-Fixing...

Kind regards
Johannes


再次



所以这里是我的第二个想法的一些示例代码来自解决方案1。



想法是根据这个扩展现有的库代码:



Hi again,

So here is some example code for my 2nd "idea" from solution1.

The idea is to extend the existing library code according to this:

public class Library
{
    public event EventHandler<ErrorOccuredEventArgs> ErrorOccured;

    // internal method, this is the method running on a separate thread
    void ThreadMethod()
    {
        // Simulate some latency
        Thread.Sleep(5000);

        // Simulate exception
        try
        {
            throw new Exception("Sample Exception");
        }
        catch(Exception ex)
        {
            // Exception occured
            OnErrorOccured(new ErrorOccuredEventArgs(ex));
        }
    }

    // call this to start the thread
    public void StartThread()
    {
        Thread thread = new Thread(ThreadMethod);
        thread.Start();
    }

    // Just raises the event, it's good style to do this in a dedicated method, so inherited classes can "disable" raising the event (proteced virtual)
    protected virtual void OnErrorOccured(ErrorOccuredEventArgs eoea)
    {
        EventHandler<erroroccuredeventargs> handler = ErrorOccured;
        if (handler != null)
            handler(this, eoea);
    }
}

// EventArgs implementation used as parameter for the ErrorOccured event.
public class ErrorOccuredEventArgs : EventArgs
{
    public ErrorOccuredEventArgs(Exception ex)
    {
        Exception = ex;
    }

    public Exception Exception { get; private set; }
}





步骤为:

1.创建新活动(这里我称之为ErrorOccured)

2.为通用EventHandler委托创建一个EventArgs实现(作为替代,您可以创建自己的委托),用作事件的处理程序类型。

3.创建一个专门的方法来引发事件(这只是一种很好的编码风格,不要直接从你代码中的variouse地方引发事件)

4.在所有例外的地方发生时,以抛出异常作为参数引发事件(通过EventArgs) - 在上面的示例中总是抛出异常。



然后调用者代码看起来像这样:



Steps are:
1. Create a new event (here i called it ErrorOccured)
2. Create an EventArgs implementation for the generic EventHandler delegate (as alternative you could create your own delegate) used as handler-type for the Event.
3. Create a dedicated method to raise the Event (this is just good coding style, don't raise events directly from variouse places in your code)
4. On all places where the exceptions occurs, raise the event with the thrown exception as parameter (via EventArgs)- in above example an exception is always thrown.

The caller code then will look something like this:

   Library lib = new Library();
            lib.ErrorOccured += lib_ErrorOccured;
            lib.StartThread();

...

void lib_ErrorOccured(object sender, ErrorOccuredEventArgs e)
        {
            MessageBox.Show(e.Exception.Message);
        }





以同样的方式创建一个ConnectionEstablished,TimoutOccured或任何你喜欢的事件。

最后,您将从Login-Forms代码附加处理程序,启动线程并等待Error或ConnectionOk(...)事件。在这些事件的处理程序内部,您可以设置状态(错误=无连接,成功=连接正常)



请注意,还有其他方法可以解决此类问题(你可以在其他线程上引发异常...),这只是一个,但在WinForms中是一个非常常见的模式。



我希望这个解决方案能给你带来想法,再次随时问任何进一步的问题....



亲切的问候

Johannes



In the same way you could create an Event "ConnectionEstablished", "TimoutOccured" or whatever you like.
In the end you will attach the handlers from you Login-Forms code, start the thread and wait for Error or ConnectionOk(...) events. Inside the handlers for these events you set your state (Error = No Connection, Success = connecting ok)

Be Aware that there are other ways to handle this kind of problem (you could raise exceptions on other threads...), this is just one, but a very common pattern in WinForms.

I hope this solution will give you the idea, again feel free to ask any further questions....

Kind regards
Johannes


这篇关于我不知道如何处理SocketException以满足我的需求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆