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

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

  1. 不在界面上用控件 动态创建idhttp,IdAntiFreeze来用

    不在界面上用控件 动态创建idhttp,IdAntiFreeze来用 var IdHTTP: Tidhttp; IdAntiFreeze: TidAntiFreeze; begin IdAntiFre ...

  2. C# DataGridView控件动态添加新行

    C# DataGridView控件动态添加新行 DataGridView控件在实际应用中非常实用,特别需要表格显示数据时.可以静态绑定数据源,这样就自动为DataGridView控件添加相应的行.假如 ...

  3. C# DataGridView控件 动态添加新行

    DataGridView控件在实际应用中非常实用,特别需要表格显示数据时.可以静态绑定数据源,这样就自动为DataGridView控件添加相应的行.假如需要动态为DataGridView控件添加新行, ...

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

     今天还是重复昨天做的事情--敲代码,但唯一的不同就是所学的知识不同了,我们又进一步往深得层次学习了,感觉越来越有意思了,虽然临近结束了看着大家积极性越来越低了,但是我知道我不能这样,我要比别人付出的 ...

  5. win32 控件的创建和消息响应

    1. 控件的创建 控件的创建和窗口创建是一样的,例如: ,,,, hWnd,(HMENU)IDB_BUTTON01,hInst,NULL); 是一个按钮的创建,其中hWnd是窗口句柄,hInst是应用 ...

  6. Delphi7 第三方控件1stClass4000的TfcImageBtn按钮控件动态加载jpg图片例子

    Delphi7 第三方控件1stClass4000的TfcImageBtn按钮控件动态加载jpg图片例子 procedure TForm1.Button1Click(Sender: TObject); ...

  7. MFC动态创建对话框中的按钮控件并创建其响应消息

    转自:http://www.cnblogs.com/huhu0013/p/4626686.html 动态按钮(多个)的创建: 1.在类中声明并定义按钮控件的ID #define IDC_D_BTN 1 ...

  8. Image控件的简单使用示例1

    Image控件加载图片包括加载动态图片,加载静态图片两种方式.一.加载动态图片通过生成一个BitmapImage,创建该对象后,赋给Image的Source即可.加载的形式: 示例1 BitmapIm ...

  9. DotNetBar RibbonControl 控件动态添加项

    想做个插件式开发,界面用Dotnetbar的RibbonControl,需要通过代码动态的向RibbonControl控件添加项 示例代码如下: RibbonTabItem rti = new Rib ...

随机推荐

  1. 【转】Android Shape绘制虚线在手机端查看是实线的问题

    Android share绘制虚线在手机上显示实线问题 给控件添加Drawableleft等图片后,单独给图片设置动画效果,参考文章: http://blog.csdn.net/langzxz/art ...

  2. OpenOffice Word文档转换成Html格式

    为什么会想起来将上传的word文档转换成html格式呢?设想,如果一个系统需要发布在页面的文章都是来自word文档,一般会执行下面的流程:使用word打开文档,Ctrl+A,进入发布文章页面,Ctrl ...

  3. Android模拟器内安装应用

    一.通过apk安装器安装应用 1.下载apk安装器(网上随便搜一个就可以) 2.下载要测试的应用的apk,我这里下载的是微信的apk 3.打开apk安装器,点击右上角的Devices选择要安装到的设备 ...

  4. in文件注意事项及详细解释

    lammps做分子动力学模拟时,需要一个输入文件(input script),也就是in文件,以及关于体系的原子坐标之类的信息文件(data file)和势文件(potential file).lam ...

  5. 最短路径Dijkstra算法(邻接矩阵)

    Dijkstra算法的原理: 从某个源点到其余各顶点的最短路径,即单源点最短路径(仅适合非负权值图).单源点最短路径是指:给定带权有向图G和源点v,求从v到G中其余各顶点的最短路径.迪杰斯特拉(Dij ...

  6. 53. Maximum Subarray (Array; DP)

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

  7. day3:vcp考试

    Q41. An administrator creates a custom ESXi firewall rule using an XML file, however the rules do no ...

  8. 各种replace待续

    http://blog.163.com/chenjie_8392/blog/static/439339842010513128139/

  9. jquery 处理重新绑定插件的方法

    比如有一个slide的jquery插件,页面打开就对dom进行了绑定. <div class="expert"> <div class="expert- ...

  10. ADF 入门帮助

    本文是由英文帮助翻译所得: 1>task flows “任务流 task flows”可以包括非可视化的组件,比如方法调用.“页片段 page fragment”可以运行在一个页面的某个局部区域 ...