1、先來看看這個
多線程編程
多線程用於數據采集時,速度明顯很快,下面是基本方法,把那個auto寫成采集數據方法即可。
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
try
{
ThreadPool.SetMaxThreads(3, 3); //設置最大線程數
for (int i = 0; i < 10; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(Auto), i);//線程池指定線程執行Auto方法
}
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public static void Auto(object i)//多線程執行的方法
{
if (string.Equals(i,2))
{
Thread.Sleep(2000);
}
Console.WriteLine(i.ToString());
}
}
}
明白吧,就是多線程執行順序是不確定的。
2、再來看看這個結果
static void Main(string[] args)
{
try
{
ThreadPool.SetMaxThreads(3, 3); //設置最大線程數
for (int i = 0; i < 10; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(Auto), i);//線程池指定線程執行Auto方法
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.WriteLine("結束了"); //這句要改
Console.ReadLine();
}
public static void Auto(object i)//多線程執行的方法
{
if (string.Equals(i, 2))
{
Thread.Sleep(2000);
}
Console.WriteLine(i.ToString());
}
結束了 這三個字不一定 真正在 最后一行輸出。因為這時是 主線程+子線程 這些線程的執行順序不確定,可能主線程老早就執行了。也就說可能結束了 這三個字很早就會輸出。
3、主題 保證 結束了 在最后輸出。
方法1:
//這是主線程,一直都會執行。目前一直在進行的是 一個主線程+多個子線程
while (true)
{
Thread.Sleep(1000);//這句寫着,主要是沒必要循環那么多次。去掉也可以。
int maxWorkerThreads, workerThreads;
int portThreads;
ThreadPool.GetMaxThreads(out maxWorkerThreads, out portThreads);
ThreadPool.GetAvailableThreads(out workerThreads, out portThreads);
if (maxWorkerThreads - workerThreads == 0)
{
Console.WriteLine("結束了");
break;
}
}
GetAvailableThreads():檢索由 GetMaxThreads 返回的線程池線程的最大數目和當前活動數目之間的差值。
而GetMaxThreads 檢索可以同時處於活動狀態的線程池請求的數目。
通過最大數目減可用數目就可以得到當前活動線程的數目,如果為零,那就說明沒有活動線程,說明所有線程運行完畢。
方法2 : Monitor
見下篇文章:http://hi.baidu.com/handboy/blog/item/681d093875d6e6cdd56225ae.html
class Program
{
static object locker = new object();
static int runningThreads = 0;
static void Main(string[] args)
{
try
{
ThreadPool.SetMaxThreads(4, 4); //設置最大線程數 using System.Threading;
runningThreads = 10;
for (int i = 0; i < runningThreads; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(Auto), i);//線程池指定線程執行Auto方法
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
lock (locker)
{
while (runningThreads > 0)
{
Monitor.Wait(locker);
}
}
Console.WriteLine("結束了");
Console.ReadLine();
}
public static void Auto(object i)//多線程執行的方法
{
if (string.Equals(i, 2))
{
Thread.Sleep(2000);
}
lock (locker)
{
runningThreads--;
Monitor.Pulse(locker);
}
Console.WriteLine(i.ToString());
}
}
方法3:WaitHandle (推薦用這個方法)
。http://hi.baidu.com/ganggang0217/blog/item/fe2a004ecad3acdcd0c86a67.html
public void testThreads()
{
ManualResetEvent[] _ManualEvents = new ManualResetEvent[10];
for (int i = 0; i < 10; i++)
{
_ManualEvents[i] = new ManualResetEvent(false);
System.Threading.ThreadPool.QueueUserWorkItem(new WaitCallback(testMethod), _ManualEvents[i]);
}
WaitHandle.WaitAll(_ManualEvents);
// 線程結束后執行后面的主線程代碼
Console.WriteLine("結束了");
Console.ReadLine();
}
public void testMethod(object objEvent)
{
//TODO: Add your code here
ManualResetEvent e = (ManualResetEvent)objEvent;
e.Set();
}
多線程編程
多線程用於數據采集時,速度明顯很快,下面是基本方法,把那個auto寫成采集數據方法即可。
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
try
{
ThreadPool.SetMaxThreads(3, 3); //設置最大線程數
for (int i = 0; i < 10; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(Auto), i);//線程池指定線程執行Auto方法
}
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public static void Auto(object i)//多線程執行的方法
{
if (string.Equals(i,2))
{
Thread.Sleep(2000);
}
Console.WriteLine(i.ToString());
}
}
}
明白吧,就是多線程執行順序是不確定的。
2、再來看看這個結果
static void Main(string[] args)
{
try
{
ThreadPool.SetMaxThreads(3, 3); //設置最大線程數
for (int i = 0; i < 10; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(Auto), i);//線程池指定線程執行Auto方法
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.WriteLine("結束了"); //這句要改
Console.ReadLine();
}
public static void Auto(object i)//多線程執行的方法
{
if (string.Equals(i, 2))
{
Thread.Sleep(2000);
}
Console.WriteLine(i.ToString());
}
結束了 這三個字不一定 真正在 最后一行輸出。因為這時是 主線程+子線程 這些線程的執行順序不確定,可能主線程老早就執行了。也就說可能結束了 這三個字很早就會輸出。
3、主題 保證 結束了 在最后輸出。
方法1:
//這是主線程,一直都會執行。目前一直在進行的是 一個主線程+多個子線程
while (true)
{
Thread.Sleep(1000);//這句寫着,主要是沒必要循環那么多次。去掉也可以。
int maxWorkerThreads, workerThreads;
int portThreads;
ThreadPool.GetMaxThreads(out maxWorkerThreads, out portThreads);
ThreadPool.GetAvailableThreads(out workerThreads, out portThreads);
if (maxWorkerThreads - workerThreads == 0)
{
Console.WriteLine("結束了");
break;
}
}
GetAvailableThreads():檢索由 GetMaxThreads 返回的線程池線程的最大數目和當前活動數目之間的差值。
而GetMaxThreads 檢索可以同時處於活動狀態的線程池請求的數目。
通過最大數目減可用數目就可以得到當前活動線程的數目,如果為零,那就說明沒有活動線程,說明所有線程運行完畢。
方法2 : Monitor
見下篇文章:http://hi.baidu.com/handboy/blog/item/681d093875d6e6cdd56225ae.html
class Program
{
static object locker = new object();
static int runningThreads = 0;
static void Main(string[] args)
{
try
{
ThreadPool.SetMaxThreads(4, 4); //設置最大線程數 using System.Threading;
runningThreads = 10;
for (int i = 0; i < runningThreads; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(Auto), i);//線程池指定線程執行Auto方法
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
lock (locker)
{
while (runningThreads > 0)
{
Monitor.Wait(locker);
}
}
Console.WriteLine("結束了");
Console.ReadLine();
}
public static void Auto(object i)//多線程執行的方法
{
if (string.Equals(i, 2))
{
Thread.Sleep(2000);
}
lock (locker)
{
runningThreads--;
Monitor.Pulse(locker);
}
Console.WriteLine(i.ToString());
}
}
方法3:WaitHandle (推薦用這個方法)
。http://hi.baidu.com/ganggang0217/blog/item/fe2a004ecad3acdcd0c86a67.html
public void testThreads()
{
ManualResetEvent[] _ManualEvents = new ManualResetEvent[10];
for (int i = 0; i < 10; i++)
{
_ManualEvents[i] = new ManualResetEvent(false);
System.Threading.ThreadPool.QueueUserWorkItem(new WaitCallback(testMethod), _ManualEvents[i]);
}
WaitHandle.WaitAll(_ManualEvents);
// 線程結束后執行后面的主線程代碼
Console.WriteLine("結束了");
Console.ReadLine();
}
public void testMethod(object objEvent)
{
//TODO: Add your code here
ManualResetEvent e = (ManualResetEvent)objEvent;
e.Set();
}