我正在开发一个 Windows 服务,该服务在一系列数据库中循环,然后使用 HTTP 请求发送 SMS 消息。在遍历每个数据库的方法的开头,我定义了一个通用列表,如下所示:
public static List<Recipient> Recipients = new List<Recipient>();
我使用通过线程池发送的异步 HTTP 请求的结果填充该列表:
//inside main method
foreach (var SMS in SMSJoin)
{
...
SMSMessage oSMS = new SMSMessage(Keyword, Number, Message, MessageID);
ThreadPool.QueueUserWorkItem(SendSMS, oSMS);
}
然后它被传递给下一个方法:
public static void SendSMS(object SMStoSend)
{
try
{
SMSMessage oSMS = (SMSMessage)SMStoSend;
...
Request.BeginGetRequestStream(new AsyncCallback(GetRequestStreamCallback), state);
}
...
}
然后去GetRequestStreamCallback
...
public static void GetRequestStreamCallback(IAsyncResult AsynchronousResult)
{
State state = (State)AsynchronousResult.AsyncState;
SMSMessage oSMS = state.oSMS;
try
{
...
Request.BeginGetResponse(new AsyncCallback(ReceiveResponse), state);
}
...
}
最后收到响应并将其添加到收件人列表中:
public static void ReceiveResponse(IAsyncResult Result)
{
...
finally
{
oSMS.Complete = DateTime.Now;
Recipient CompleteMessage = new Recipient(oSMS.MessageID, oSMS.Recipient, oSMS.ErrorCode, oSMS.Complete, oSMS.ResponseCode);
Recipients.Add(CompleteMessage);
}
在代码的最后,每个响应都应该被添加到一个Recipient
对象中,然后存储在通用列表中。问题是大约每 1000 条左右的 SMS 消息(分批发送 50 条)一次IndexOutOfRangeException
,代码行会抛出一个未处理的消息Recipients.Add(CompleteMessage)
。
没想到列表里有索引,很多收件人都是重复的。为什么它会抛出这个错误,为什么每隔一段时间才会抛出一次?这可能与线程问题有关吗?
请注意,我正在从一个Timer
对象激活 main 方法,但它会等到前一个实例完成后再启动一个新实例。
编辑:
这是Recipient
课程:
public class Recipient
{
public Recipient(long MessageID, string PhoneNumber, string ErrorMessage, DateTime? Completed, string Response)
{
this.MessageID = MessageID;
this.PhoneNumber = PhoneNumber;
this.ErrorMessage = ErrorMessage;
this.Completed = Completed;
this.Response = Response;
}
public long MessageID { get; set; }
public string PhoneNumber { get; set; }
public string ErrorMessage { get; set; }
public DateTime? Completed { get; set; }
public string Response { get; set; }
}