日期:2014-05-17  浏览次数:20786 次

100分,一个优化挑战问题,请大家帮忙,解决一下多线程的问题,谢谢.
小弟现在做一个信息的系统,现在设计出来的信息的发送程序是单线程的.一天如果发送的信息量超过10万就会很慢,但现在平台的需求是一天有几十万,所以想改成多线程的,但本人对多线程又不熟悉,还请大家多帮忙.大概思路是先使用一个线程从数据库内取数据出来,然后用一个或多个(最好是多个)线程负责专门的发送,然后再用一个线程负责把发送好的结果往数据库内更新,请大家帮帮忙,用c#帮我写一下例子参与,谢谢.

------解决方案--------------------
你这个问题太大,不好描述,

我的建议,你用一个或者两个队列(可以用LinkedList类来实现)作为线程的交换数据,取数据线程,不一定从数据库读取1000条,你可以用DataReader来读取所有的数据,每读到一条数据就生成一个实体类实例并放入发送队列中,实体类包含要发送的内容和结果,

发送线程可以预先启动,可以比读取线程先启动,发送线程内部是一个死循环,用信号量控制读取发送队列,一旦有数据进入队列就恢复运行,否则就阻塞等待队列中有内容,一旦队列中有数据放入,发送线程的死循环就从队列中取出实体类实例,执行发送操作,完成后把结果写入实体类实例,然后把实例放入另一个队列,比如保存队列中中,

然后保存线程也是预先启动好,也是个死循环,不断读取保存队列,用信号量控制,有实体类进入保存队列保存线程就恢复运行,然后把结果写入数据库,也可以批量写入以提高效率,

------解决方案--------------------
除了Thread类之外,你可以看信号量Semaphore 类,这个类用来控制队列的读写很完美,可以让读取线程、发送线程和保存线程的速度一致,
------解决方案--------------------
关注......期待......
------解决方案--------------------
每个线程中处理10个,不用再次创建10个线程,单个线程去处理10个足以,只要你保证读取数据线程和处理线程要同步,即读完了,处理,处理完了,再次读取
------解决方案--------------------
1天10万看起来不算多,但要知道每条数据的信息量是多少,如果每条都很大呢?

先检查瓶颈吧,到底是在网络还是在内部运算(包括取数据)。

网络是用udp还是tcp,对方有没有接收到是怎么判断的,这些都可能成为瓶颈。



------解决方案--------------------
随手写的!这是代码,你测试看下是否正确
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Collections;
using System.Threading;

namespace ConsoleApplication1
{
class Program
{
static SqlConnection con = new SqlConnection("Data Source=IP;Initial Catalog=数据库;User ID=sa;Password=;");
static SqlDataAdapter da;
static List<cescasio> GetListces = new List<cescasio>();//数据
static List<cescasio> SetListces = new List<cescasio>();//更新数据
static bool state = false;//是否创建线程

/// <summary> 获取数据 </summary>
static void GetData()
{
while (true) //采集数据
{
if (GetListces.Count == 0)//如果没有数据了采集数据
{
state = false;//停止
DataTable Dt = new DataTable();
con.Open();
da = new SqlDataAdapter("select top 1000 from 数据表", con);//查询语句
da.Fill(Dt);
con.Close();
for (int i = 0; i < Dt.Rows.Count; i++)
{
cescasio cess = new cescasio();
cess.xingming = Dt.Rows[i]["xingming"].ToString();
cess.ip = Dt.Rows[i]["id"].ToString();//主键
cess.id = Dt.Rows[i]["ip"].ToString();
GetListces.Add(cess);
}
state = true;//采集完毕 开始发送数据
}
Thread.Sleep(1000);//一秒一次自己控制
}

}

/// <summary>更新数据 </summary>
static void Update()
{
while (true)
{
if (SetListces.Count > 0)
{
//.....更新数据

//这个自己写吧
}
Thread.Sleep(10000);//十秒执行一次更新数据你自己控制
}

}
/// <summary>创建线程 </summary>
static void Create_Th()
{
while (true) //采集数据
{
if (state && GetListces.Count > 0)//是否创建