У меня есть приложение 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, но это похоже на убийство. Любые предложения приветствуются!
Любой асинхронный подход должен сделать трюк. Например, используя Task
или (если вы используете.NET 4. 5+) метод async
. (Не забудьте обработать асинхронные ошибки, поставив обратный вызов с помощью чего-то вроде .ContinueWith()
чтобы проверить задачу на наличие ошибок и ответить соответствующим образом.)
Разумеется, в этом случае проблема с ошибками может быть сложной. Это похоже на операцию, в которой вы хотите продолжать повторять попытку в случае сбоя (с протоколированием в случае постоянных сбоев) и определенно хотите продолжить цикл, даже если одно сообщение не удалось. Так что может быть что-то немного более ручное.
Для этого я бы рекомендовал сохранить сами сообщения в простой таблице базы данных из приложения и продолжить работу с пользовательским интерфейсом по вашему желанию. Затем у вас есть отдельное приложение, такое как служба Windows, который периодически обследует эту таблицу базы данных и отправляет сообщения в простой цикл по записям.
Хорошим подходом для чего-то подобного было бы сохранить простой флаг состояния в записях сообщений. Очередь, отправленная, ошибка (с сообщением об ошибке) и т.д. Служба Windows может обновлять записи при отправке сообщений в цикле. Как и любые сообщения об ошибках, просто обновите эту запись и продолжайте цикл. Повторно отправьте сообщения об ошибках.