Рабочий процесс, необходимый для выполнения длительной задачи ASP.NET

1

У меня есть приложение ASP.NET WebForms, которое имитирует систему справочной службы. Приложение работает отлично, но недавно они попросили меня сделать так, чтобы он мог отправлять текстовые сообщения всем в систему всякий раз, когда открывается новый билет справочной службы.

Я использую Twilio для этого, и он работает нормально. Единственная проблема заключается в том, что в системе есть 15 человек, которые должны получать это текстовое сообщение, и когда билет отправляется, приложение занимает около 15-20 секунд, чтобы отправить сообщение из submit. В будущем может быть более 15 человек, вдвое больше.

Я задаюсь вопросом, есть ли способ отправить эти сообщения в фоновом режиме, чтобы страница вернулась из отправки сразу. Вот мой код:

Это мой основной метод, который я написал для отправки текстового сообщения. Его в классе Utility:

    public static string SendSms(string phoneNumber, string message)
    {
        var request = (HttpWebRequest)WebRequest.Create("https://api.twilio.com/2010-04-01/Accounts/" + Constants.TwilioId + "/Messages.json");
        string postData = "From=" + Constants.TwilioFromNumber + "&To=+1" + phoneNumber + "&Body=" + HttpUtility.HtmlEncode(message);
        byte[] data = Encoding.ASCII.GetBytes(postData);
        string authorization = string.Format("{0}:{1}", Constants.TwilioId, Constants.TwilioAuthToken);
        string encodedAuthorization = Convert.ToBase64String(Encoding.ASCII.GetBytes(authorization));
        string credentials = string.Format("{0} {1}", "Basic", encodedAuthorization);

        request.Method = "POST";
        request.ContentType = "application/x-www-form-urlencoded";
        request.ContentLength = data.Length;
        request.Headers[HttpRequestHeader.Authorization] = credentials;

        using (var stream = request.GetRequestStream())
        {
            stream.Write(data, 0, data.Length);
        }

        string responseString;
        using (var response = (HttpWebResponse) request.GetResponse())
        {
            using (var reader = new StreamReader(response.GetResponseStream()))
            {
                responseString = reader.ReadToEnd();
            }
        }

        return responseString;
    }

И вот как я это называю:

public void BtnSubmit_Click(object sender, EventArgs e)
{
    //
    // This is more code here, but its irrelevant
    //

    var employees = new Employees();
    employees.GetAll();

    foreach (Employee employee in employees)
    {
        string number = employee.CellPhoneAreaCode + employee.CellPhonePrefix +
                        employee.CellPhoneSuffix;
        if (!string.IsNullOrEmpty(number) && number.Length == 10)
        {
            Utility.SendSms(number, "A new Help Desk Ticket is in the System!");
        }
    }
}

Единственная другая идея, которую я могу придумать, - создать службу WCF, но это похоже на убийство. Любые предложения приветствуются!

  • 2
    Один из подходов может заключаться в том, чтобы ставить сообщения в очередь в простой таблице базы данных, а затем использовать службу Windows, опрашивающую таблицу и отправляющую сообщения.
  • 0
    @David Дэвид. Было бы лучше создать службу Windows или лучше создать службу WCF, где я могу просто передать ей 10 цифр, а служба WCF поставит их в очередь и отправит?
Показать ещё 3 комментария
Теги:
twilio
webforms

1 ответ

2
Лучший ответ

Любой асинхронный подход должен сделать трюк. Например, используя Task или (если вы используете.NET 4. 5+) метод async. (Не забудьте обработать асинхронные ошибки, поставив обратный вызов с помощью чего-то вроде .ContinueWith() чтобы проверить задачу на наличие ошибок и ответить соответствующим образом.)

Разумеется, в этом случае проблема с ошибками может быть сложной. Это похоже на операцию, в которой вы хотите продолжать повторять попытку в случае сбоя (с протоколированием в случае постоянных сбоев) и определенно хотите продолжить цикл, даже если одно сообщение не удалось. Так что может быть что-то немного более ручное.

Для этого я бы рекомендовал сохранить сами сообщения в простой таблице базы данных из приложения и продолжить работу с пользовательским интерфейсом по вашему желанию. Затем у вас есть отдельное приложение, такое как служба Windows, который периодически обследует эту таблицу базы данных и отправляет сообщения в простой цикл по записям.

Хорошим подходом для чего-то подобного было бы сохранить простой флаг состояния в записях сообщений. Очередь, отправленная, ошибка (с сообщением об ошибке) и т.д. Служба Windows может обновлять записи при отправке сообщений в цикле. Как и любые сообщения об ошибках, просто обновите эту запись и продолжайте цикл. Повторно отправьте сообщения об ошибках.

  • 0
    Интересно, что я собираюсь заняться этим типом функциональности электронной почты в приложении. Я искал существующие коммерческие компоненты или компоненты с открытым исходным кодом, которые делают это (поскольку я хотел бы не быть 1298726-м разработчиком, чтобы написать один), но не смог найти ни одного. Не вдаваться в новый вопрос, но есть ли у кого-нибудь тот, с кем они работали раньше?
  • 0
    @JimMSDN: В большинстве корпоративных сценариев я следовал этому же подходу для отправки электронных писем по нескольким причинам. 1) Ведет учет сообщений, которые могут пригодиться позже. 2) Он абстрагирует среду обмена сообщениями, позволяя пользователям настраивать различные виды сообщений, не связанных с электронной почтой, без необходимости большого количества нового кода. 3) При обмене большими объемами даже необычные ошибки становятся обычным явлением, и этот автономный подход к отправке обрабатывает ошибки очень эффективно.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню