【问题标题】:Custom Exceptions and Message Dialog in Try-Catch clauseTry-Catch 子句中的自定义异常和消息对话框
【发布时间】:2015-09-17 18:01:45
【问题描述】:

我开发了一个通用应用程序,它需要几个自定义异常来捕获调用 web 服务时遇到的错误:NoInternetAccessException、NoJSONException、UserTimeoutException、...

这是这些类之一的示例:

    public class NoInternetAccessException : Exception
    {
        private DateTime time;

        public DateTime Time { get { return time; } }

        public NoInternetAccessException(string message, DateTime time) 
            : base(message)
        {
            this.time = time;
        }
    }

我在几个地方发现了这些异常:

JSONParser 中,我在其中创建 URI 并调用 Client.GetAsync 方法:

    ...
    try
    {
        CancellationTokenSource cts = new CancellationTokenSource(Timeout);
        response = await client.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead).AsTask(cts.Token);
        if (response.IsSuccessStatusCode)
            return response;                   
    }
    catch (TaskCanceledException)
    {
        if ((_currentRetries == MaxRetries)
            throw new UserTimeoutException("User Timeout Exception", DateTime.Now);
        else
            _currentRetries++;
    }
    catch (Exception e)
    {
        if (e.HResult == -2147012889)
            throw new WrongUrlException("Wrong URL Exception", e, DateTime.Now);
    }
    ...

WebService 帮助程序中,我管理所有 Web 服务调用:

    public static async Task<Infos> GetInfos(String url, List<KeyValuePair<String, String>> parameters, String protocol)
    {        
        var response = await JSONParser.getJSONFromUrl(url, parameters, "");
        Infos infos = new Infos();

        try
        {
            WsResponse wsResponse = JsonConvert.DeserializeObject<Infos>(response.ToString());
            infosCe = JsonConvert.DeserializeObject<Infos>(wsResponse.data.ToString());
            return infosCe;
        }
        catch (Exception e)
        {
            throw new DeserializeException("Deserialize exception", e, DateTime.Now, "Infos");
        }
    }

在调用 web 服务之后,所有这些异常最终被 ViewModel 捕获

    private async Task<Infos> WebServiceGetInfos()
    {
        ...
        try
        {
            Infos infos = await WebServices.GetInfos(url, parameters, "");
            return infosCe;
        }

        // Exceptions
        catch (DeserializeException dE)
        {
            ExceptionsMsgboxHelper.MsgboxDeserialize(dE);
            return null;
        }
        catch (NoInternetAccessException niaE)
        {
            ExceptionsMsgboxHelper.MsgboxNoInternetAccess(niaE, true, "");
            return null;
        }
        catch (NoJSONException njsonE)
        {
            ExceptionsMsgboxHelper.MsgboxNoJSON(njsonE);
            return null;
        }
        ...
    }

我希望每个异常都调用 ExceptionsMsgboxHelper 帮助器,它会为每个异常显示一个特定的消息对话框:

    public async static void MsgboxNoJSON(NoJSONException njsonE)
    {
        Windows.UI.Popups.MessageDialog msgbox =
        new Windows.UI.Popups.MessageDialog("There is a problem when retrieving data. If the problem persists, please contact your administrator.",
            "Unexpected data received");
        await msgbox.ShowAsync();
    }

=>但这不起作用,因为消息对话框在 Try-Catch 子句中不起作用...

我也在stackoverflow上寻找解决方案:

Message dialog not showing in catch clause

Try-Catch doesn't show Message Dialog box with await

但我不知道如何使这个解决方案适应我的情况,因为我使用了几个自定义异常:

    public static async Task Foo()
    {
        Exception e = null;
        try
        {
            //just something to throw an exception
            int a = 0;
            int n = 1 / a;
        }
        catch (Exception ex)
        {
            e = ex;
        }
        if (e != null)
            await ShowDialog();
    }

=> 执行此操作是否比将此代码复制到每个自定义异常更好?

    ...
    DeserializeException dEx = null;
    NoInternetAccessException niaEx = null;
    NoJSONException njsonEx = null;
    try
    {
        Infos infos = await WebServices.GetInfos(url, parameters, "");
        return infosCe;
    }

    // Exceptions
    catch (DeserializeException dE)
    {
        dEx = de;
    }
    catch (NoInternetAccessException niaE)
    {
        niaEx = niaE;
    }
    catch (NoJSONException njsonE)
    {
        njsonEx=njsonE;
    }
    ...
    if (dEx != null)
    {
        ExceptionsMsgboxHelper.MsgboxDeserialize(dEx);
        return null;
    }
    if (niaEx != null)
    {
        ExceptionsMsgboxHelper.MsgboxNoInternetAccess(niaEx);
        return null;
    }
    if (njsonEx != null)
    {
        ExceptionsMsgboxHelper.MsgboxNoJSON(njsonEx);
        return null;
    }
    ...

=> 它似乎并不强大或可维护......

【问题讨论】:

    标签: c# async-await try-catch custom-exceptions messagedialog


    【解决方案1】:

    我终于通过捕获一个通用异常并对其进行测试解决了我的问题:

        ...
        Exception ex = null;
        try
        {
            Infos infos = await WebServices.GetInfos(url, parameters, "");
            return infosCe;
        }
    
        // Exceptions
        catch (Exception e)
        {
            ex = e;
        }
        if (ex != null)
        {
            if (ex is DeserializeException)
            {
                DeserializeException dE = (DeserializeException)ex;
                ExceptionsMsgboxHelper.MsgboxDeserialize(dE);
            }
            if (ex is NoInternetAccessException)
            {
                NoInternetAccessException niaE = (NoInternetAccessException)ex;
                ExceptionsMsgboxHelper.MsgboxNoInternetAccess(niaE);
            }
            if (ex is NoJSONException)
            {
                NoJSONException njsonE = (NoJSONException)ex;
                ExceptionsMsgboxHelper.MsgboxNoJSON(njsonE);
            }
            ...
        }
        return null;
    

    =>如果您认为有更好的方法可以做到这一点,请指出。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-01-05
      • 2021-09-08
      • 2013-04-15
      • 2013-12-10
      • 1970-01-01
      • 1970-01-01
      • 2023-03-25
      • 1970-01-01
      相关资源
      最近更新 更多