在进行多线程设计过程中,最重要的就是实现线程同步和线程界面交互。如果想实现线程同步,可以通过lock锁来进行;而如果要想线程和界面交互,则需要利用委托来进行,下面请看代码:

using System;
using System.Windows.Forms;
using System.Threading;

namespace UpdateUIFromThreadAPP
{
public partial class MainFrm : Form
{
public MainFrm()
{
InitializeComponent();
this.DoubleBuffered = true;
}

private object lockShopkeeper = new object(); //the flag of locking state
private Good[] goods; // good array
private static int sum = 0; // summery of the goods' price



private void MainFrm_Load(object sender, EventArgs e)
{
InitGoods();
OpenThread();
}

//init the storage
private void InitGoods()
{
Good cabbage
= new Good { GoodName = "白菜", GoodNumber = 20, GoodPrice = 12 };
Good radish
= new Good { GoodName = "萝卜", GoodNumber = 43, GoodPrice = 3 };
Good celery
= new Good { GoodName = "芹菜", GoodNumber = 15, GoodPrice = 7 };
Good onion
= new Good { GoodName = "洋葱", GoodNumber = 78, GoodPrice = 2 };
Good egg
= new Good { GoodName = "鸡蛋", GoodNumber = 124, GoodPrice = 1 };

goods
= new Good[5];
goods[
0] = cabbage;
goods[
1] = radish;
goods[
2] = celery;
goods[
3] = onion;
goods[
4] = egg;

for (int i = 0; i < 5; i++)
{
Good temp
= goods[i];
ListViewItem lvi
= new ListViewItem();
lvi.Text
= temp.GoodName + " 数量:" + temp.GoodNumber + " 单价:" + temp.GoodPrice + " 总价:" + temp.GoodNumber * temp.GoodPrice;
lsvStoreGoods.Items.Add(lvi);
//add the info to the first listview
}
}

//generate the random num of buying
private int SellNum()
{
Random ran
= new Random();
return ran.Next(1,10);
}

//get the index of a good
private int GetGoodIndex()
{
Random ran
= new Random();
return ran.Next(0, 5);
}

/// <summary>
/// start to buy goods in 1000 threads
/// </summary>
private void OpenThread()
{
int threadNum = 1000; // the person buying the goods, here I sets it to 1000.
Thread[] thread = new Thread[threadNum];
for (int i = 0; i < threadNum; i++)
{
Thread _thread
= thread[i];
_thread
= new Thread(new ParameterizedThreadStart(Open));
_thread.Start((
object)goods[GetGoodIndex()]);
}
}

private void Open(object _good)
{
Good good
= _good as Good;
lock (lockShopkeeper)
{
int _selNum = SellNum();
if (good.GoodNumber >= _selNum)
{
good.GoodNumber
= good.GoodNumber - _selNum;
Thread.Sleep(
500);
UpdateStorage(good);
UpdateSell(good, _selNum);
UpdateProfit(good, _selNum);
}
else
{
if (good.GoodNumber > 0)
{
Thread.Sleep(
500);
_selNum
= good.GoodNumber;
good.GoodNumber
= 0;
UpdateStorage(good);
UpdateSell(good, _selNum);
UpdateProfit(good, _selNum);
}
}
}
}

private delegate void UpdateStorageDelegate(Good good);
private delegate void UpdateSellDelegate(Good good, int num);
private delegate void UpdateProfitDelegate(Good good, int num);
private delegate void UpdateProgressInfoDelegate(int sum);
private delegate void UpdateProgressDelegate(int sum);

private void UpdateStorage(Good good)
{
if (lsvStoreGoods.InvokeRequired)
{
lsvStoreGoods.Invoke(
new UpdateStorageDelegate(UpdateStorage), good);
}
else
{
ListViewItem lvi
= lsvStoreGoods.FindItemWithText(good.GoodName, false, 0, true);
lvi.Text
= good.GoodName + " 数量:" + good.GoodNumber + " 单价:" + good.GoodPrice + " 总价:" + good.GoodNumber * good.GoodPrice;
}
}

private void UpdateSell(Good good, int num)
{
if (lsvSellGoods.InvokeRequired)
{
lsvSellGoods.Invoke(
new UpdateSellDelegate(UpdateSell),good,num);
}
else
{
ListViewItem lvi
=new ListViewItem();
lvi.Text
="卖出"+good.GoodName+" 单价:"+good.GoodPrice+" 数量:"+num+" 获得利润:"+num*good.GoodPrice;
lsvSellGoods.Items.Add(lvi);
}
}

private void UpdateProfit(Good good, int num)
{
if (lsvTotal.InvokeRequired)
{
lsvTotal.Invoke(
new UpdateProfitDelegate(UpdateProfit), good, num);
}
else
{
ListViewItem lvi
= lsvTotal.FindItemWithText("销售总额", false, 0, true);
sum
+= num * good.GoodPrice;
UpdateProgress(sum);
UpdateProgressInfo(sum);
lvi.Text
= "销售总额" + sum;
}
}

private void UpdateProgress(int sum)
{
if (pbInfo.InvokeRequired)
{
pbInfo.Invoke(
new UpdateProgressDelegate(UpdateProgress), sum);
}
else
{
pbInfo.Value
= sum;
}
}

private void UpdateProgressInfo(int sum)
{
if (lblInfo.InvokeRequired)
{
lblInfo.Invoke(
new UpdateProgressInfoDelegate(UpdateProgressInfo), sum);
}
else
{
lblInfo.Text
= (double)((double)sum / (double)754) * 100 + "%";
}
}

}
}

看下跑的效果图:

posted on 2011-08-31 22:50  程序诗人  阅读(762)  评论(0编辑  收藏  举报