BMDThread控件动态创建多线程示例

http://www.cnblogs.com/railgunman/archive/2010/12/08/1900688.html

BMDThread控件是一套相当成熟的线程控件,使用它可以让你快速的创建、管理线程。 
   可以到CSDN或者盒子上下载BMDThread控件。 
   下面我们用多线程模拟客户端发送文件的例子来简单认识一下它。 
   在窗体中放置一个TIDClient,TBMDThread,TBMDThreadGroup.三个TEdit,两个按钮(开始线程,结束线程),一个MEMO用于接受线程结果信息 
   功能:使用IDTCPClient向指定服务器发送文件,动态创建线程数量同步发送文件。

开始创建我们的线程单元吧。 
新建Unit,保存为ThreadUnit.pas。 
在单元接口部分需要引用BMDThread 单元。为了方便下面的代码编写,把Windows,Classes单元也引用。

首先,因为IP,端口,需要创建的线程数都是动态的,所以需要向我们的线程提供。

注: TFileStream.Create 最后一个参数意义: 
打开模式:   
fmCreate   :用指定的文件名建立文件,如果文件已经存在则打开它。   
fmOpenRead   :以只读方式打开指定文件   
fmOpenWrite   :以只写方式打开指定文件   
fmOpenReadWrite:以写写方式打开指定文件   
共享模式:   
fmShareCompat   :共享模式与FCBs兼容   
fmShareExclusive:不允许别的程序以任何方式打开该文件   
fmShareDenyWrite:不允许别的程序以写方式打开该文件   
fmShareDenyRead   :不允许别的程序以读方式打开该文件   
fmShareDenyNone   :别的程序可以以任何方式打开该文件 
代码如下: 
unit ThreadUnit;

interface 
uses 
Windows, Classes, SysUtils, BMDThread, IdTCPClient;

type

TSendMsg = procedure(Owner: TObject; ThreadID: Integer; Msg: string) of object;

TSendThread= class(TBMDThread) 
      private 
        FHost: string; 
        FPort: Integer; 
        FThreadID: integer; 
        FSendmsg: string; 
        FOnSendMsg: TSendMsg; 
        procedure DoSend; 
        procedure SetSendMsg(const Value: TSendMsg); 
      protected 
         procedure Execute(); override; 
         procedure DoSendMsg(Sender: TObject); 
      public 
        constructor Create(Owner: TComponent; Host: string; Port, ThreadID: Integer); 
        destructor Destroy(); override; 
        property OnSendMsg: TSendMsg read FOnSendMsg write SetSendMsg; 
    end;

implementation

{ TSendThread }

constructor TSendThread.Create(Owner: TComponent; Host: string; Port, ThreadID: Integer); 
begin 
FHost:= Host; 
FPort:= Port; 
FThreadID:= ThreadID; 
inherited Create(Owner); 
end;

destructor TSendThread.Destroy; 
begin 
inherited; 
end;

procedure TSendThread.DoSend; 
var 
IdTCPClient:TIdTCPClient; 
fs:TFileStream; 
FileName: string; 
begin 
inherited; 
try 
    FileName:= ‘E:\text.txt‘; 
    try 
      IdTCPClient := TIdTCPClient.Create(nil); 
      try 
        IdTCPClient.Host := FHost; 
        IdTCPClient.Port := FPort; 
        IdTCPClient.Connect; 
        fs:= TFileStream.Create(FileName, FmOpenRead or fmShareDenyNone); 
        fs.Position:= 0; 
        fs.Seek(0, 0 ); 
        IdTCPClient.WriteLn(‘<SEND>‘ + FileName); 
        IdTCPClient.WriteStream(fs); 
        FSendmsg := ‘发送成功‘; 
        Thread.Synchronize(DoSendMsg); 
      except on E: Exception do 
        begin 
          FSendmsg := ‘连接错误:‘ + e.Message; 
          Thread.Synchronize(DoSendMsg); 
        end; 
      end; 
    finally 
      FreeAndNil(fs); 
      IdTCPClient.Disconnect; 
      IdTCPClient.free; 
    end; 
except

end; 
end;

procedure TSendThread.DoSendMsg(Sender: TObject); 
begin 
if Assigned(FOnSendMsg) then 
    FOnSendMsg(Sender, FThreadID, FSendmsg); 
end;

procedure TSendThread.Execute; 
begin 
//while not Thread.Terminated DO //如果你想你的代码一直进行下去直至线程结束,可以这么做 
    doSend; 
end;

procedure TSendThread.SetSendMsg(const Value: TSendMsg); 
begin 
FOnSendMsg:= Value; 
end;

end.

主单元代码:

unit MainUnit;

interface

uses 
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
Dialogs, StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection, 
IdTCPClient, BMDThread;

type 
TForm1 = class(TForm) 
    BMDThread1: TBMDThread; 
    BMDThreadGroup1: TBMDThreadGroup; 
    IdTCPClient1: TIdTCPClient; 
    edt_Host: TEdit; 
    lbl1: TLabel; 
    lbl2: TLabel; 
    edt_Port: TEdit; 
    lbl3: TLabel; 
    edt_Count: TEdit; 
    btn_Send: TButton; 
    btn_Stop: TButton; 
    mmo1: TMemo; 
    btn1: TButton; 
    procedure btn_SendClick(Sender: TObject); 
    procedure GetMsg(Sender: TObject; ThreadID: Integer; Msg: string); 
    procedure btn_StopClick(Sender: TObject); 
    procedure btn1Click(Sender: TObject); 
private 
    { Private declarations } 
public 
    { Public declarations } 
end;

var 
Form1: TForm1;

implementation 
uses ThreadUnit; 
{$R *.dfm}

procedure TForm1.btn_SendClick(Sender: TObject); 
var 
i: Integer; 
SendThread: TSendThread; 
begin 
btn_Stop.Click; 
for i:= 1 to StrToInt(edt_Count.Text) do 
begin 
    SendThread:= TSendThread.Create(Self,edt_Host.Text, StrToInt(edt_Port.Text),I); 
    try 
      SendThread.ThreadGroup:= BMDThreadGroup1; 
      SendThread.OnSendMsg:= GetMsg; 
    except 
      SendThread.Free; 
    end; 
end; 
for i:= 0 to BMDThreadGroup1.ThreadsCount - 1 do 
begin 
    SendThread:= TSendThread(BMDThreadGroup1.ThreadItems[i]) ; 
    try 
      SendThread.Start ; 
    except 
      On E: Exception do 
      begin 
        SendThread.Stop ; 
        SendThread.Thread.WaitFor; 
      end; 
    end; 
end; 
end;

procedure TForm1.GetMsg(Sender: TObject; ThreadID: Integer; Msg: string); 
begin 
mmo1.Lines.Add(FormatDateTime(‘yyyy-mm-dd hh:mm:ss‘,Now) + ‘ 线程ID:‘ + IntToStr(ThreadID)+ Msg); 
end;

procedure TForm1.btn_StopClick(Sender: TObject); 
var 
SendThread: TBMDThread; 
begin 
BMDThreadGroup1.Stop() ; 
while BMDThreadGroup1.ThreadsCount > 0 do 
begin 
    SendThread:= BMDThreadGroup1.Threads[BMDThreadGroup1.ThreadsCount -1] ; 
    try 
      if SendThread.Thread <> nil then 
      begin 
        SendThread.Stop() ; 
        SendThread.Thread.WaitFor ; 
      end; 
    except 
    end; 
    BMDThreadGroup1.RemoveThread(SendThread); 
end; 
end;

procedure TForm1.btn1Click(Sender: TObject); 
begin 
mmo1.Clear; 
end;

end.

来源:http://www.wesoho.com/article/Delphi/2882.htm

时间: 2024-10-12 08:05:13

BMDThread控件动态创建多线程示例的相关文章

C# DataGridView控件动态添加新行

C# DataGridView控件动态添加新行 DataGridView控件在实际应用中非常实用,特别需要表格显示数据时.可以静态绑定数据源,这样就自动为DataGridView控件添加相应的行.假如需要动态为DataGridView控件添加新行,方法有很多种,下面简单介绍如何为DataGridView控件动态添加新行的两种方法: 方法一: int index=this.dataGridView1.Rows.Add(); this.dataGridView1.Rows[index].Cells[

Swift学习之函数和简单地控件的创建

 今天还是重复昨天做的事情--敲代码,但唯一的不同就是所学的知识不同了,我们又进一步往深得层次学习了,感觉越来越有意思了,虽然临近结束了看着大家积极性越来越低了,但是我知道我不能这样,我要比别人付出的更多,更加的踏实才行,因为我知道我的基础不如别人,目标和动力也和他们不同,看着大家有的说是只要找到工作就好,还有的说只要每个月够花就好,担着真的是大家来这里学习的最终目的吗,如果是这样,真的还不如随便找个工作将就一下,也比这个整天做到这好多了,还交了那么贵得费用,所以何必呢,既然选择了这条路,既然当

C# DataGridView控件 动态添加新行

DataGridView控件在实际应用中非常实用,特别需要表格显示数据时.可以静态绑定数据源,这样就自动为DataGridView控件添加相应的行.假如需要动态为DataGridView控件添加新行,方法有很多种,下面简单介绍如何为DataGridView控件动态添加新行的两种方法: 方法一: int index=this.dataGridView1.Rows.Add(); this.dataGridView1.Rows[index].Cells[0].Value = "1"; thi

win32 控件的创建和消息响应

1. 控件的创建 控件的创建和窗口创建是一样的,例如: //-------- 创建窗口或控件 ----hwnd = CreateWindow("button","myButton01", WS_VISIBLE|WS_CHILD, 80,60,35,25, hWnd,(HMENU)IDB_BUTTON01,hInst,NULL); 是一个按钮的创建,其中hWnd是窗口句柄,hInst是应用程序句柄. 其他控件类似的可以把第一个参数"button"改

第三章 按钮控件的创建

一.前言 不知不觉一晃两个月过去,说来惭愧,在此期间alterto一直没有再研究DuiEngine.主要是因为DuiEngine的作者现在构建一个新的界面库soui,而笔者也一直处于观望状态,因为DuiEngine的作者说了以后可能就不维护DuiEngine了,要把主要的经历放在SOUI上.alterto顿时犹豫了,既然这样我还为DuiEngine做什么教程啊.于是这两个月的时间里一直都很犹豫,也没有再出DuiEngine相关的教程.现在看来这种焦躁对于一个优秀的程序猿来说着实不应该,这也正暴露

C# Winform控件动态删除

WPF控件的动态删除请参考WPF动态删除指定类型控件 今天在实现控件动态删除过程中遇到了点小Trouble,就是在删除的过程中只能删除一半,具体代码如下: foreach (var control in from ctls in controlUtility.GetControls(panel1) where ctls.Name.StartsWith("BtnTable") select ctls) { panel1.Controls.Remove(control); control.

事件委托应用:在父控件中创建子控件,并接收值

传值过程使用委托方法 定义一个打开按扭,一个文本框 1 /// <summary> 2 /// 增加父控件 3 /// </summary> 4 public void AddParent(BaseControl ctl) 5 { 6 foreach (Control ct2 in this.Parent.Controls) 7 { 8 if (ct2.Name == ctl.Name) { 9 ct2.Focus(); 10 return; 11 } 12 } 13 ctl.Wi

swift基础控件的创建

/* let apples = 3 let orange = 5 let L = 1.1 let appleSummary = "I have \(apples) apples" let fruitSummary = "I have \(apples + orange) pieces of fruit." let isay = "I Love \(L) you " print(isay) let expliciFloat: Float = 4 /

树控件CTreeCtrl 创建与双击响应

函数功能:创建一个树控件,并实现双击节点响应事件. 响应方法:在树控件上增加双击响应事件. 代码: 1.在OnInitDialog中:   CTreeCtrl *ctreectrl = (CTreeCtrl *)GetDlgItem(IDC_TREE1);  //调用ModifyStyle方法修改数控件Sytle  ctreectrl->ModifyStyle(0,TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS);  //设置树控件字体颜色  ct