读书人

100分请问多线程的有关问题,测试通过马

发布时间: 2012-01-05 22:36:54 作者: rapoo

100分请教多线程的问题,测试通过马上结帖
我有个表里面储藏了

很多FLASH的URL

比如有10万条记录

现在我想开10个线程,每个线程下载一个FLASH

如果其中有个线程完成任务了,那么程序马上就在开一个线程

这样保证最多有10个线程在下载数据

该怎么做啊,知道的朋友请教教我



[解决办法]
把例子给你贴出来:

使用回调方法检索数据
下面的示例演示了一个从线程中检索数据的回调方法。包含数据和线程方法的类的构造函数也接受代表回调方法的委托;在线程方法结束前,它调用该回调委托。

using System;
using System.Threading;

// The ThreadWithState class contains the information needed for
// a task, the method that executes the task, and a delegate
// to call when the task is complete.
//
public class ThreadWithState {
// State information used in the task.
private string boilerplate;
private int value;

// Delegate used to execute the callback method when the
// task is complete.
private ExampleCallback callback;

// The constructor obtains the state information and the
// callback delegate.
public ThreadWithState(string text, int number,
ExampleCallback callbackDelegate)
{
boilerplate = text;
value = number;
callback = callbackDelegate;
}

// The thread procedure performs the task, such as
// formatting and printing a document, and then invokes
// the callback delegate with the number of lines printed.
public void ThreadProc()
{
Console.WriteLine(boilerplate, value);
if (callback != null)
callback(1);
}
}

// Delegate that defines the signature for the callback method.
//
public delegate void ExampleCallback(int lineCount);

// Entry point for the example.
//
public class Example
{
public static void Main()
{
// Supply the state information required by the task.
ThreadWithState tws = new ThreadWithState(
"This report displays the number {0}. ",
42,
new ExampleCallback(ResultCallback)
);

Thread t = new Thread(new ThreadStart(tws.ThreadProc));
t.Start();
Console.WriteLine( "Main thread does some work, then waits. ");
t.Join();
Console.WriteLine(
"Independent task has completed; main thread ends. ");
}

// The callback method must match the signature of the
// callback delegate.
//
public static void ResultCallback(int lineCount)
{
Console.WriteLine(
"Independent task printed {0} lines. ", lineCount);
}
}
[解决办法]
1.有一个父线程,控制子线程的创建、并控制并发数量。
2.子线程中有一个完成事件,当下载完成一个FLASH的时候触发它。
3.父线程捕获子线程的完成事件,将当前并发数量减少。
[解决办法]
你所要做的就是在这里:

public void ThreadProc()
{
Console.WriteLine(boilerplate, value);
if (callback != null)
callback(1);
}

-> >

public void ThreadProc()
{
//进行下载
//下载完成,CallBack,当然要判断此时表中存储的URL是否都已经用完,如果没有了,那也不用再CallBack了..

}

你的CallBack函数,即回调函数中就是启动一个纯程的操作...

[解决办法]
写了个小例子,不知道能不能说明问题..

//互斥量
static Mutex mx = new Mutex();
//用于存储资源
static ArrayList list = new ArrayList();



//定义一个变量,标识线程索引
static int indexOfThread = 0;

//定义一个变量,用于标识当前线程的数量
static int countOfThread = 0;

static void Main(string[] args)
{
//ArrayList中存储100个数,相当于一百个资源
for (int i = 0; i < 100; i++)
{
list.Add(i);
}

//先启动10个线程
for (int i = 0; i < 10; i++)
{
mx.WaitOne();
int ii = Convert.ToInt32(list[0]);
list.RemoveAt(0);
Thread thread = new Thread(new ParameterizedThreadStart(ThreadProc));
thread.Name = "Thread " + indexOfThread++.ToString();
thread.Start(ii);
//当前的线程数目增1
countOfThread++;
Debug.WriteLine(thread.Name + "启动,当前总的线程数为: " + countOfThread);
mx.ReleaseMutex();
}
Console.ReadLine();

}
public static void ThreadProc(object i)
{
Debug.WriteLine(Thread.CurrentThread.Name + " : " + i.ToString());
Thread.Sleep(1000);
CallBack();
}

public static void CallBack()
{
mx.WaitOne();

//当前线程数自减1
countOfThread--;

//如果当前还有资源待下载,并且当前的线程的数量小于10
if (list.Count > 0 && countOfThread < 10)
{
int ii = Convert.ToInt32(list[0]);
list.RemoveAt(0);
Thread thread = new Thread(new ParameterizedThreadStart(ThreadProc));
thread.Name = "Thread " + indexOfThread++.ToString();
thread.Start(ii);
//当前的线程数目增1
countOfThread++;
Debug.WriteLine(thread.Name + "启动,当前总的线程数为: " + countOfThread);
}
mx.ReleaseMutex();
}
[解决办法]
输出:
Thread0启动,当前总的线程数为:1
Thread0 : 0
Thread1启动,当前总的线程数为:2
Thread1 : 1
Thread2启动,当前总的线程数为:3
Thread2 : 2
Thread3启动,当前总的线程数为:4
Thread3 : 3
Thread4启动,当前总的线程数为:5
Thread5启动,当前总的线程数为:6
Thread5 : 5
Thread6 : 6
Thread6启动,当前总的线程数为:7
Thread4 : 4
Thread7启动,当前总的线程数为:8
Thread7 : 7
Thread8 : 8
Thread8启动,当前总的线程数为:9
Thread9启动,当前总的线程数为:10
Thread9 : 9
Thread10启动,当前总的线程数为:10
Thread10 : 10
Thread11启动,当前总的线程数为:10
Thread11 : 11
Thread12启动,当前总的线程数为:10
Thread12 : 12
Thread13启动,当前总的线程数为:10
Thread13 : 13
Thread14启动,当前总的线程数为:10
Thread14 : 14
Thread15启动,当前总的线程数为:10
Thread15 : 15
Thread16启动,当前总的线程数为:10
Thread16 : 16
Thread17启动,当前总的线程数为:10
Thread17 : 17
Thread18启动,当前总的线程数为:10
Thread18 : 18
Thread19启动,当前总的线程数为:10
Thread19 : 19
Thread20启动,当前总的线程数为:10
Thread20 : 20
Thread21启动,当前总的线程数为:10
Thread21 : 21
Thread22启动,当前总的线程数为:10
Thread22 : 22
Thread23启动,当前总的线程数为:10
Thread23 : 23
Thread24启动,当前总的线程数为:10
Thread24 : 24
Thread25启动,当前总的线程数为:10
Thread25 : 25
Thread26启动,当前总的线程数为:10
Thread26 : 26
Thread27启动,当前总的线程数为:10
Thread27 : 27
Thread28启动,当前总的线程数为:10
Thread28 : 28
Thread29启动,当前总的线程数为:10
Thread29 : 29
Thread30启动,当前总的线程数为:10
Thread30 : 30
Thread31启动,当前总的线程数为:10
Thread31 : 31
Thread32启动,当前总的线程数为:10
Thread32 : 32


Thread33启动,当前总的线程数为:10
Thread33 : 33
Thread34启动,当前总的线程数为:10
Thread34 : 34
Thread35启动,当前总的线程数为:10
Thread35 : 35
Thread36启动,当前总的线程数为:10
Thread36 : 36
Thread37启动,当前总的线程数为:10
Thread37 : 37
Thread38启动,当前总的线程数为:10
Thread38 : 38
Thread39启动,当前总的线程数为:10
Thread39 : 39
Thread40启动,当前总的线程数为:10
Thread40 : 40
Thread41启动,当前总的线程数为:10
Thread41 : 41
Thread42启动,当前总的线程数为:10
Thread42 : 42
Thread43启动,当前总的线程数为:10
Thread43 : 43
Thread44启动,当前总的线程数为:10
Thread44 : 44
Thread45启动,当前总的线程数为:10
Thread45 : 45
Thread46启动,当前总的线程数为:10
Thread46 : 46
Thread47启动,当前总的线程数为:10
Thread47 : 47
Thread48启动,当前总的线程数为:10
Thread48 : 48
Thread49启动,当前总的线程数为:10
Thread49 : 49
Thread50启动,当前总的线程数为:10
Thread50 : 50
Thread51启动,当前总的线程数为:10
Thread51 : 51
Thread52启动,当前总的线程数为:10
Thread52 : 52
Thread53启动,当前总的线程数为:10
Thread53 : 53
Thread54启动,当前总的线程数为:10
Thread54 : 54
Thread55启动,当前总的线程数为:10
Thread55 : 55
Thread56启动,当前总的线程数为:10
Thread56 : 56
Thread57启动,当前总的线程数为:10
Thread57 : 57
Thread58启动,当前总的线程数为:10
Thread58 : 58
Thread59启动,当前总的线程数为:10
Thread59 : 59
Thread60启动,当前总的线程数为:10
Thread60 : 60
Thread61启动,当前总的线程数为:10
Thread61 : 61
Thread62启动,当前总的线程数为:10
Thread62 : 62
Thread63启动,当前总的线程数为:10
Thread63 : 63
Thread64启动,当前总的线程数为:10
Thread64 : 64
Thread65启动,当前总的线程数为:10
Thread65 : 65
Thread66启动,当前总的线程数为:10
Thread66 : 66
Thread67启动,当前总的线程数为:10
Thread67 : 67
Thread68启动,当前总的线程数为:10
Thread68 : 68
Thread69启动,当前总的线程数为:10
Thread69 : 69
Thread70启动,当前总的线程数为:10
Thread70 : 70
Thread71启动,当前总的线程数为:10
Thread71 : 71
Thread72启动,当前总的线程数为:10
Thread72 : 72
Thread73启动,当前总的线程数为:10
Thread73 : 73
Thread74启动,当前总的线程数为:10
Thread74 : 74
Thread75启动,当前总的线程数为:10
Thread75 : 75
Thread76启动,当前总的线程数为:10
Thread76 : 76
Thread77启动,当前总的线程数为:10
Thread77 : 77
Thread78启动,当前总的线程数为:10
Thread78 : 78
Thread79启动,当前总的线程数为:10
Thread79 : 79
Thread80启动,当前总的线程数为:10
Thread80 : 80
Thread81启动,当前总的线程数为:10
Thread81 : 81
Thread82启动,当前总的线程数为:10
Thread82 : 82
Thread83启动,当前总的线程数为:10
Thread83 : 83
Thread84启动,当前总的线程数为:10
Thread84 : 84
Thread85启动,当前总的线程数为:10
Thread85 : 85
Thread86启动,当前总的线程数为:10
Thread86 : 86
Thread87启动,当前总的线程数为:10
Thread87 : 87
Thread88启动,当前总的线程数为:10
Thread88 : 88
Thread89启动,当前总的线程数为:10
Thread89 : 89
Thread90启动,当前总的线程数为:10
Thread90 : 90
Thread91启动,当前总的线程数为:10
Thread91 : 91
Thread92启动,当前总的线程数为:10
Thread92 : 92
Thread93启动,当前总的线程数为:10
Thread93 : 93
Thread94启动,当前总的线程数为:10
Thread94 : 94
Thread95启动,当前总的线程数为:10
Thread95 : 95
Thread96启动,当前总的线程数为:10
Thread96 : 96
Thread97启动,当前总的线程数为:10
Thread97 : 97
Thread98启动,当前总的线程数为:10
Thread98 : 98
Thread99启动,当前总的线程数为:10
Thread99 : 99

[解决办法]
试试下面的代码:
public class MutexTest
{
private static int poolFlag = 0 ;//标记
private const int amountThread = 10 ;//线程总量
private const int maxThread = 3 ;//可执行线程最大数量
private static Mutex muxConsole = new Mutex() ;

public static void Main()
{
for ( int i = 0 ; i < amountThread ; i ++ )
{
// 创建指定数量的线程
// 是线程调用Run方法
// 启动线程
Thread trd = new Thread( new ThreadStart( Run ) ) ;
trd.Name = "线程 " + i ;
trd.Start() ;
}
}


public static void Run()
{

muxConsole.WaitOne(); //阻塞队列
Interlocked.Increment(ref poolFlag) ; //标记+1
if (poolFlag != maxThread) //判断是否等于上限
muxConsole.ReleaseMutex(); //如果此线程达不到可执行线程上限,则继续开通,让后面的线程进来
Console.WriteLine( "{0} 正在运行......\n ", Thread.CurrentThread.Name ) ;
Thread.Sleep( 5000 ); //模拟执行
Console.WriteLine( "{0} 已经中止......\n ", Thread.CurrentThread.Name ) ;

//标记-1
Interlocked.Decrement(ref poolFlag) ;
}
}


注释很全,大家慢慢看吧~我准备把这个用到WebService的负载平衡上面~

这样我就可以自己控制请求的数量了~

-----------------------------------
使用类、类的方法或类的属性都可以向线程传递参数:
public class UrlDownloader
{
string url;
public UrlDownloader (string url)
{
this.url = url;

} public void Download()
{ WebClient wc = new WebClient();
Console.WriteLine( "Downloading " + url);
byte[] buffer = wc.DownloadData (url);
string download = Encoding.ASCII.GetString(buffer);
Console.WriteLine(download);
Console.WriteLine( "Download successful. ");
//这里你可以将download进行保存等处理...... }}[... 在另一个类中使用它们...] UrlDownloader downloader = new UrlDownloader (yourUrl);new Thread (new ThreadStart (downloader.Download)).Start();
注意参数是如何传递的。
在.NET 2.0中还可以这样:
(CODE-BESIDE)方式一:
ThreadStart starter = delegate { Download(yourUrl); });new Thread(starter).Start();//使用线程池WaitCallback callback = delegate (object state) { Download ((string)state); };ThreadPool.QueueUserWorkItem (callback, yourUrl);方式二(使用ParameterizedThreadStart):Thread t = new Thread (new ParameterizedThreadStart(DownloadUrl));t.Start (myUrl);static void DownloadUrl(object url){ // ....}
[解决办法]
liujia_0421(SnowLover)

你的方法会不会出现这样的情形: 系统反复的创建线程和销毁线程.

我觉得可以在程序开始的时候,只启动10个线程, 就一直使用这10个线程

将所有任务列表做成一条公共队列,

每个线程都有一个函数方法循环去队列里拿任务, 完成一个任务,在继续去取任务

直到公共的队列里没有任务. 线程函数退出循环

当然要注意队列的线程同步问题


[解决办法]
TO:你的方法会不会出现这样的情形: 系统反复的创建线程和销毁线程.

差不多吧..不过线程都是自动结束的,所以也谈不上销毁...

我也是照楼主的意思做的..

你的想法也很好...
[解决办法]
哦,你的是2003,ParameterizedThreadStart这个委托是VS2005新增的,用于线程传参的..

如果不需要传参,可以用ThreadStart,如果要传参,Vs2003需要将线程过程和参数都封装在类中..

我给你的第一个例子,就是那么做的..

可以再给你一个简单点的例子,你一看就明白..MSDN上的..


using System;
using System.Threading;

// The ThreadWithState class contains the information needed for
// a task, and the method that executes the task.
//
public class ThreadWithState {
// State information used in the task.
private string boilerplate;
private int value;

// The constructor obtains the state information.
public ThreadWithState(string text, int number)
{
boilerplate = text;
value = number;
}

// The thread procedure performs the task, such as formatting
// and printing a document.
public void ThreadProc()
{
Console.WriteLine(boilerplate, value);
}
}

// Entry point for the example.
//
public class Example {
public static void Main()
{
// Supply the state information required by the task.
ThreadWithState tws = new ThreadWithState(
"This report displays the number {0}. ", 42);


// Create a thread to execute the task, and then
// start the thread.
Thread t = new Thread(new ThreadStart(tws.ThreadProc));
t.Start();
Console.WriteLine( "Main thread does some work, then waits. ");
t.Join();
Console.WriteLine(
"Independent task has completed; main thread ends. ");
}
}

读书人网 >C#

热点推荐