ASP.NET MVC AsyncController Обработка исключений - PullRequest
0 голосов
/ 04 января 2012

В ASP.NET MVC я пытаюсь написать действие асинхронного контроллера со старой моделью асинхронного программирования (фактически, это текущая, новая все еще CTP).

Здесь я пытаюсь запустить 4 операции параллельно, и это сработало отлично.Вот полный код:

public class SampleController : AsyncController {

    public void IndexAsync() {

        AsyncManager.OutstandingOperations.Increment(4);

        var task1 = Task<string>.Factory.StartNew(() => {

            return GetReponse1();
        });
        var task2 = Task<string>.Factory.StartNew(() => {

            return GetResponse2();
        });
        var task3 = Task<string>.Factory.StartNew(() => {

            return GetResponse3();
        });
        var task4 = Task<string>.Factory.StartNew(() => {

            return GetResponse4();
        });

        task1.ContinueWith(t => {

            AsyncManager.Parameters["headers1"] = t.Result;
            AsyncManager.OutstandingOperations.Decrement();
        });

        task2.ContinueWith(t => {

            AsyncManager.Parameters["headers2"] = t.Result;
            AsyncManager.OutstandingOperations.Decrement();
        });

        task3.ContinueWith(t => {

            AsyncManager.Parameters["headers3"] = t.Result;
            AsyncManager.OutstandingOperations.Decrement();
        });

        task4.ContinueWith(t => {

            AsyncManager.Parameters["headers4"] = t.Result;
            AsyncManager.OutstandingOperations.Decrement();
        });

        task3.ContinueWith(t => {

            AsyncManager.OutstandingOperations.Decrement();

        }, TaskContinuationOptions.OnlyOnFaulted);
    }

    public ActionResult IndexCompleted(string headers1, string headers2, string headers3, string headers4) {

        ViewBag.Headers = string.Join("<br/><br/>", headers1, headers2, headers3, headers4);

        return View();
    }

    public ActionResult Index2() {

        ViewBag.Headers = string.Join("<br/><br/>", GetReponse1(), GetResponse2(), GetResponse3(), GetResponse4());

        return View();
    }
}

И вот эти ниже методы, которые выполняются асинхронные операции:

string GetReponse1() {

    var req = (HttpWebRequest)WebRequest.Create("http://www.twitter.com");
    req.Method = "HEAD";

    var resp = (HttpWebResponse)req.GetResponse();

    return FormatHeaders(resp.Headers);
}

string GetResponse2() {

    var req2 = (HttpWebRequest)WebRequest.Create("http://stackoverflow.com");
    req2.Method = "HEAD";

    var resp2 = (HttpWebResponse)req2.GetResponse();

    return FormatHeaders(resp2.Headers);
}

string GetResponse3() {

    var req = (HttpWebRequest)WebRequest.Create("http://google.com");
    req.Method = "HEAD";

    var resp = (HttpWebResponse)req.GetResponse();

    return FormatHeaders(resp.Headers);
}

string GetResponse4() {

    var req = (HttpWebRequest)WebRequest.Create("http://github.com");
    req.Method = "HEAD";

    var resp = (HttpWebResponse)req.GetResponse();

    return FormatHeaders(resp.Headers);
}

private static string FormatHeaders(WebHeaderCollection headers) {

    var headerStrings = from header in headers.Keys.Cast<string>()
                        select string.Format("{0}: {1}", header, headers[header]);

    return string.Join("<br />", headerStrings.ToArray());
}

У меня также есть Index2 метод, который является синхронным иделает то же самое.

Я сравниваю два времени выполнения операции, и есть большая разница (приблизительно 2 секунды)

Но я думаю, что мне здесь не хватает многих вещей (обработка исключений, таймауты,так далее).Я реализую обработку исключений только в задаче 3, но не думаю, что это правильный способ сделать это.

Какой самый здоровый способ обработки исключений для операций такого типа?

1 Ответ

3 голосов
/ 04 января 2012

Прежде чем получить доступ к результату задачи, вы должны проверить, успешно ли оно выполнено.Если произошла ошибка, вы не должны пытаться получить доступ к результатам, а вместо этого сделать что-то с исключением:

task1.ContinueWith(t => 
{
    if (!t.IsFaulted)
    {
        AsyncManager.Parameters["headers1"] = t.Result;
    }
    else if (t.IsFaulted && t.Exception != null)
    {
        AsyncManager.Parameters["error"] = t.Exception;
    }
    AsyncManager.OutstandingOperations.Decrement();
});
...