0

对于我的 ios 应用程序,我需要处理那些服务器返回错误的情况,我有兴趣处理一些错误,例如 Not Found 和 Timed Out。

我正在使用 Xamarin 和 Windows Azure 移动服务进行开发。到目前为止,我知道如何捕获这些异常,但是,如果出现异常,我想显示一个包含刷新按钮的视图,用户可以按下该按钮以进行刷新(转到服务器并查看是否有新数据,删除刷新视图,并显示新信息)。

这就是我捕获服务器抛出的异常的方式:

    public async RefreshAsync(){           
        try
        {
            var results = await DailyWorkoutTable.ToListAsync();
            wod = results.FirstOrDefault();
            SetupUI();  
        }
        catch(Exception e)
        {
            var ex = e.GetBaseException() as MobileServiceInvalidOperationException;
            if(ex.Response.StatusCode == 404)
            {
                //this is where I need to set up the refresh view and
                //and add a UIButton to it
                Console.WriteLine("Daily workout not found");
            }
        }
    }

我不知道实现这一目标的正确方法是什么。如果我创建一个 UIView 并向其添加一个 UIButton,并使用一个再次调用 RefreshAsync 的事件,它将不起作用,也不是最优雅的方法。

还有另一种方法吗?请帮忙。

4

1 回答 1

1

这是一个可以用作起点的示例:

/// <summary>
/// A class for performing Tasks and prompting the user to retry on failure
/// </summary>
public class RetryDialog
{
    /// <summary>
    /// Performs a task, then prompts the user to retry if it fails
    /// </summary>
    public void Perform(Func<Task> func)
    {
        func().ContinueWith(t =>
        {
            if (t.IsFaulted)
            {
                //TODO: you might want to log the error

                ShowPopup().ContinueWith(task =>
                {
                    if (task.IsCompleted)
                        Perform(func);

                }, TaskScheduler.FromCurrentSynchronizationContext());
            }

        }, TaskScheduler.FromCurrentSynchronizationContext());
    }

    /// <summary>
    /// Wraps a retry/cancel popup in a Task
    /// </summary>
    private Task ShowPopup()
    {
        var taskCompletionSource = new TaskCompletionSource<bool>();

        var alertView = new UIAlertView("", "Something went wrong, retry?", null, "Ok", "Cancel");
        alertView.Dismissed += (sender, e) => {
            if (e.ButtonIndex == 0)
                taskCompletionSource.SetResult(true);
            else
                taskCompletionSource.SetCanceled();
        };
        alertView.Show();

        return taskCompletionSource.Task;
    }
}

要使用它:

var retryDialog = new RetryDialog();
retryDialog.Perform(() => DoSomethingThatReturnsTask());

这个例子在 async/await 支持之前,但是如果需要你可以重构它。

您也可以考虑让 Perform() 返回一个 Task 并变成异步的——这取决于您的用例。

于 2013-04-27T15:53:32.567 回答