使用异步和事件代理提高用户体验(短信群发)

使用手机、移动终端经常会用到群发信息,群发信息过程中,如果把终端设备(如手机)看成共享资源,把发送每一条信息当作单独一个进程。多个进程共享一个终端。

程序设计:

1.移动终端

AxTransoftSMSControl30.AxSMS MyAxSMS; // 这里的终端使用短信猫控件

AxSMS:

属性:

    bool IsBusy;  // 控件状态

事件:

    MsgReceived;  // 接收到短信

    SendComplete; // 发送成功

    Error;        // 发送出错

    InComingCall; // 新来电

2.接收人

 

public class Person {
public string Name { get; set; }
public string Phone { get; set; }
}

3.短消息

 

public class SMS {
public string Sender { get; set; }
public string Receiver { get; set; }
public string Content { get; set; }
}

需求分析:

实现短信群发,记录群发日志,当短信内容超过70字时分多条发送。

代码实现:

添加声明控件是否忙碌:

private bool isBusy = false;

发送短信代理:

private delegate object SendSMSHandlter(Person person, SMS sms);

发送短信成功代理:

private delegate void SendSMSCompletedHandlter(object sender, SendSMSCompletedEventArgs);

发送短信完成事件:虽然短信控件已经有了这样的事件,可是为了系统将短信分多条发送:

private event SendSMSCompletedHandlter SendSMSCompleted;

使用队列保存接收人信息:

private Queue<Person> sendingPersonQueue = new Queue<Person>();

每条短信的最大长度:

private int SMS_Message_Max_Length = 70;

发送短信:

private object SendOneMessage(Person person, SMS sms) {
string temp = sms.Content;
if (sms.Content.Length > SMS_Message_Max_Length) {
int _i = sms.Content.Length / SMS_Message_Max_Length;
if (_i * SMS_Message_Max_Length < sms.Content.Length) {
_i
++;
string[] arr = new string[_i];
int j = 0;
while (j < _i) {
if (temp.Length >= SMS_Message_Max_Length) {
arr[j]
= temp.Substring(0, SMS_Message_Max_Length - 1);
temp
= temp.Substring(SMS_Message_Max_Length);
}
else {
arr[j]
= temp;
temp
= string.Empty;
}
while (this.MyAxSMS.IsBusy) {
System.Threading.Thread.Sleep(
200);
}
if (!this.MyAxSMS.IsBusy) {
this.MyAxSMS.SendMsg(person.PhoneNumber, arr[j], true, true, false);
}
j
++;
}
return 1;
}
}
else {
while (this.MyAxSMS.IsBusy) {
System.Threading.Thread.Sleep(
200);
}
if (!this.MyAxSMS.IsBusy) {
this.MyAxSMS.SendMsg(person.PhoneNumber, sms.Content, true, true, false);
return 1;
}
}
return 0;
}
使用异步模式

 

public void SendOneMessageAsync(Person receivePerson, SMS sms) {
SendSMSHandlter ss
= new SendSMSHandlter(SendOneMessage);
ss.BeginInvoke(receivePerson, sms,
new AsyncCallback(SendOneMessageCallback), ss);
}

private void SendOneMessageCallback(IAsyncResult ar) {
SendSMSHandlter ss
= ar.AsyncState as SendSMSHandlter;
object result = ss.EndInvoke(ar);
if (result != null) {
if (SendSMSCompleted != null) {
object[] rs = new Object[1];
rs[
0] = result;
SendSMSCompletedEventArgs e
= new SendSMSCompletedEventArgs(rs);
this.SendSMSCompleted(this, e);
}
}
}

开始发送短信:

 

private void Send() {
while (this.sendingPersonQueue.Count > 0) {
if (!this.IsBusy) { // 系统是不是忙碌
this.IsBusy = true;
Person person
= this.sendingPersonQueue.Dequeue();
this.SendOneMessageAsync(person, sms);
this.SendSMSCompleted = new SendSMSCompletedHandlter(FormMain_SendSMSCompleted);
}
else {
System.Threading.Thread.Sleep(
500);
}
}
}

单条短信发送成功 

public void FormMain_SendSMSCompleted(object sender, SendSMSCompletedEventArgs e) {

   this.IsBusy = false;

}


这样可有效避免循环发送时候因为短信控件繁忙,而导致发送失败的问题。

SendSMSCompletedEventArgs 代码没有贴出,完全可以使用 EventArgs。

posted @ 2011-01-24 16:52 XueM Views(...) Comments(...) Edit 收藏