用多线程提升效率

bychgh 2010-03-12 06:52:03
用winform做了个群发短信,用来给客户发送相关信息,当客户量非常多的时候,比如发完10000完短信就要等很长时间,程序常出现假死,很不。。,,有没办法改进下,多线程本人不太懂,请高手修改下代码:

//str1-9 的定义就不贴了
IList<Model.sendMes> messList = new SQLServerDAL.sendMes().GetAllList(" *", null, "id desc");

FULLTUNNELCONTROLLib.FullTunnelServiceControlClass my = new FULLTUNNELCONTROLLib.FullTunnelServiceControlClass();

int successNum = 0;

for (int i = 0; i < messList.Count; i++)
{

str5 = messList[i].mobilephone.ToString(); //手机号码
int ErrorMessage = Convert.ToInt32(my.FullTunnelServiceControl(ref str1, ref str2, ref str3, ref str4, ref str5, ref str6, ref str7, ref str8, ref str9));

if (ErrorMessage.ToString() == "1")
{
successNum = successNum + 1;
}
}

this.txtmessage.Text = "总共 " + messList.Count + " 条短信 " + " 发送成功 " + successNum.ToString() + " 条短信";

MessageBox.Show("发送完毕");


如果能加上进度条就很好了,一定另外加分
...全文
231 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
xingyuebuyu 2010-03-13
  • 打赏
  • 举报
回复
BackgroundWorker 类允许您在单独的专用线程上运行操作。耗时的操作(如下载和数据库事务)在长时间运行时可能会导致用户界面 (UI) 似乎处于停止响应状态。如果您需要能进行响应的用户界面,而且面临与这类操作相关的长时间延迟,则可以使用 BackgroundWorker 类方便地解决问题。

若要在后台执行耗时的操作,请创建一个 BackgroundWorker,侦听那些报告操作进度并在操作完成时发出信号的事件。可以通过编程方式创建 BackgroundWorker,也可以将它从“工具箱”的“组件”选项卡中拖到窗体上。如果在 Windows 窗体设计器中创建 BackgroundWorker,则它会出现在组件栏中,而且它的属性会显示在“属性”窗口中。

若要设置后台操作,请为 DoWork 事件添加一个事件处理程序。在此事件处理程序中调用耗时的操作。若要启动该操作,请调用 RunWorkerAsync。若要收到进度更新通知,请对 ProgressChanged 事件进行处理。若要在操作完成时收到通知,请对 RunWorkerCompleted 事件进行处理。

注意
您必须非常小心,确保在 DoWork 事件处理程序中不操作任何用户界面对象。而应该通过 ProgressChanged 和 RunWorkerCompleted 事件与用户界面进行通信。

BackgroundWorker 事件不跨 AppDomain 边界进行封送处理。请不要使用 BackgroundWorker 组件在多个 AppDomain 中执行多线程操作。


如果后台操作需要参数,请在调用 RunWorkerAsync 时给出参数。在 DoWork 事件处理程序内部,可以从 DoWorkEventArgs.Argument 属性中提取该参数。

有关 BackgroundWorker 的更多信息,请参见 如何:在后台运行操作。





给你的链接上讲得很清楚了啊,调用RunWorkerAsync会触发DoWork 事件,你在这个事件中做你需要长时间运算的方法就好了.有参数就传参数,可以从 DoWorkEventArgs.Argument属性中提取该参数,也可以不传的,它有两个重载方法,然后在这个事件中调用其ReportProcess方法报告进度
bychgh 2010-03-13
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 xingyuebuyu 的回复:]
用BackgroundWorker组件吧.
RunWorkerAsync()方法开始后台执行
ReportProgress()方法就可以汇报进度

参考下面的就可以了
http://msdn.microsoft.com/zh-cn/library/system.componentmodel.backgroundworker(VS.80).aspx
[/Quote]

RunWorkerAsync要的参数是什么?
maomao198907 2010-03-13
  • 打赏
  • 举报
回复
进度条很好解决,添加一个精度条,先将进度条Maximum值设为短信条数(或小点,比如除以10),每发一条进度条value值加1或10,就这么简单!
yaoyaomeiying 2010-03-12
  • 打赏
  • 举报
回复
可以研究研究。。。。。。。。。。。
whb147 2010-03-12
  • 打赏
  • 举报
回复
主要是处理一个进度条,让用户看到你在干活
billow_chentao 2010-03-12
  • 打赏
  • 举报
回复
学习.........
龙宜坡 2010-03-12
  • 打赏
  • 举报
回复
明显是需要一个后台线程避免用于界面失去响应,利用BackGroundWorker组件实现。



using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace DelegateSample
{
/*********************************************************************
* 2009-10-29 guog,老鸟绕道!
* 跨线程控件访问示例:
* 因为.NET2.0以后禁止对控件跨线程访问,
* 所以可以使用委托来实现。
* 这是其中一种方法
*********************************************************************/
/// <summary>
/// 这里声明一个委托供线程调用
/// </summary>
/// <param name="txt"></param>
public delegate void AppendTextHandler(string txt);

public partial class Form1 : Form
{
Thread m_trd = null;
//实例化一个委托对象
AppendTextHandler m_handler = null;

public Form1()
{
InitializeComponent();
}

/// <summary>
/// 窗体Load 事件
/// </summary>
/// <param name="e"></param>
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
//实例化一个委托对象
m_handler = new AppendTextHandler(AppendTextText);

//开启新线程
m_trd = new Thread(new ThreadStart(OtherThreadDoSomething));
m_trd.Start();
}

/// <summary>
/// 关闭窗体时结束创建的线程
/// </summary>
/// <param name="e"></param>
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
if (m_trd != null)
{
m_trd.Abort();
}
}

/// <summary>
/// 线程执行的方法
/// </summary>
private void OtherThreadDoSomething()
{
string _str;
while (Thread.CurrentThread.ThreadState!=ThreadState.Aborted)
{//线程未请求终止就一直执行
_str = System.Guid.NewGuid().ToString();
AppendTextText(_str);
Thread.Sleep(50);//可去掉
}
}

/// <summary>
/// 向当前窗体控件中增加文本
/// </summary>
/// <param name="txt"></param>
private void AppendTextText(string txt)
{
if (this.richTextBox1.InvokeRequired)
{//调用方在另外一个线程中
//在拥有此控件的线程上执行委托指向的方法
this.richTextBox1.Invoke(m_handler, txt);
}
else
{//调用方在当前线程中
this.richTextBox1.AppendText(txt + "\r\n");//增加文本
this.richTextBox1.ScrollToCaret();//滚动到当前目录
}
}
}
}
xingyuebuyu 2010-03-12
  • 打赏
  • 举报
回复
用BackgroundWorker组件吧.
RunWorkerAsync()方法开始后台执行
ReportProgress()方法就可以汇报进度

参考下面的就可以了
http://msdn.microsoft.com/zh-cn/library/system.componentmodel.backgroundworker(VS.80).aspx
bychgh 2010-03-12
  • 打赏
  • 举报
回复
高手帮处理下吧
happyboyxq1985 2010-03-12
  • 打赏
  • 举报
回复
应该用异步处理吧。
bychgh 2010-03-12
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 wo65432519 的回复:]
多线程也不会提升你发短信的效率啊!
LZ是想另开一线程处理这10000个客户的短信发送,还是开对应客户的线程数处理短信发送(10000个线程哦!可以利用线程池优化!)??
[/Quote]

只是想优化下效率
Joe-xXx 2010-03-12
  • 打赏
  • 举报
回复
多线程也不会提升你发短信的效率啊!
LZ是想另开一线程处理这10000个客户的短信发送,还是开对应客户的线程数处理短信发送(10000个线程哦!可以利用线程池优化!)??
我姓区不姓区 2010-03-12
  • 打赏
  • 举报
回复
参考

System.Threading.Thread th = new System.Threading.Thread(delegate(object obj)
{
//str1-9 的定义就不贴了
IList<Model.sendMes> messList = new SQLServerDAL.sendMes().GetAllList(" *", null, "id desc");

FULLTUNNELCONTROLLib.FullTunnelServiceControlClass my = new FULLTUNNELCONTROLLib.FullTunnelServiceControlClass();

int successNum = 0;

for (int i = 0; i < messList.Count; i++)
{

str5 = messList[i].mobilephone.ToString(); //手机号码
int ErrorMessage = Convert.ToInt32(my.FullTunnelServiceControl(ref str1, ref str2, ref str3, ref str4, ref str5, ref str6, ref str7, ref str8, ref str9));

if (ErrorMessage.ToString() == "1")
{
successNum = successNum + 1;
}
}

this.txtmessage.Text = "总共 " + messList.Count + " 条短信 " + " 发送成功 " + successNum.ToString() + " 条短信";

MessageBox.Show("发送完毕");

});
th.Start();
bancxc 2010-03-12
  • 打赏
  • 举报
回复
帮顶 学习

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧