使用异步和事件代理提高用户体验(短信群发)
使用手机、移动终端经常会用到群发信息,群发信息过程中,如果把终端设备(如手机)看成共享资源,把发送每一条信息当作单独一个进程。多个进程共享一个终端。
程序设计:
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。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?