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
BMDThread控件动态创建多线程示例的更多相关文章
- 不在界面上用控件 动态创建idhttp,IdAntiFreeze来用
不在界面上用控件 动态创建idhttp,IdAntiFreeze来用 var IdHTTP: Tidhttp; IdAntiFreeze: TidAntiFreeze; begin IdAntiFre ...
- C# DataGridView控件动态添加新行
C# DataGridView控件动态添加新行 DataGridView控件在实际应用中非常实用,特别需要表格显示数据时.可以静态绑定数据源,这样就自动为DataGridView控件添加相应的行.假如 ...
- C# DataGridView控件 动态添加新行
DataGridView控件在实际应用中非常实用,特别需要表格显示数据时.可以静态绑定数据源,这样就自动为DataGridView控件添加相应的行.假如需要动态为DataGridView控件添加新行, ...
- Swift学习之函数和简单地控件的创建
今天还是重复昨天做的事情--敲代码,但唯一的不同就是所学的知识不同了,我们又进一步往深得层次学习了,感觉越来越有意思了,虽然临近结束了看着大家积极性越来越低了,但是我知道我不能这样,我要比别人付出的 ...
- win32 控件的创建和消息响应
1. 控件的创建 控件的创建和窗口创建是一样的,例如: ,,,, hWnd,(HMENU)IDB_BUTTON01,hInst,NULL); 是一个按钮的创建,其中hWnd是窗口句柄,hInst是应用 ...
- Delphi7 第三方控件1stClass4000的TfcImageBtn按钮控件动态加载jpg图片例子
Delphi7 第三方控件1stClass4000的TfcImageBtn按钮控件动态加载jpg图片例子 procedure TForm1.Button1Click(Sender: TObject); ...
- MFC动态创建对话框中的按钮控件并创建其响应消息
转自:http://www.cnblogs.com/huhu0013/p/4626686.html 动态按钮(多个)的创建: 1.在类中声明并定义按钮控件的ID #define IDC_D_BTN 1 ...
- Image控件的简单使用示例1
Image控件加载图片包括加载动态图片,加载静态图片两种方式.一.加载动态图片通过生成一个BitmapImage,创建该对象后,赋给Image的Source即可.加载的形式: 示例1 BitmapIm ...
- DotNetBar RibbonControl 控件动态添加项
想做个插件式开发,界面用Dotnetbar的RibbonControl,需要通过代码动态的向RibbonControl控件添加项 示例代码如下: RibbonTabItem rti = new Rib ...
随机推荐
- HttpClient 4 和 HttpClient 3 超时
HttpClient 4: 连接超时: httpclient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,6000 ...
- 二叉树的创建、遍历(递归和非递归实现)、交换左右子数、求高度(c++实现)
要求:以左右孩子表示法实现链式方式存储的二叉树(lson—rson),以菜单方式设计并完成功能任务:建立并存储树.输出前序遍历结果.输出中序遍历结果.输出后序遍历结果.交换左右子树.统计高度,其中对于 ...
- Python bytearray() 函数
Python bytearray() 函数 Python 内置函数 描述 bytearray() 方法返回一个新字节数组.这个数组里的元素是可变的,并且每个元素的值范围: 0 <= x < ...
- .NET中的文件IO操作实例
1.写入文件代码: //1.1 生成文件名和设置文件物理路径 Random random = new Random(DateTime.Now.Millisecond); ); string Physi ...
- 没有无线路由,如何让手机使用电脑的网络xyytit
前言: 智能手机已经越来越普遍,但国内的无线网络的步伐还是没有跟上智能机的脚步.纵使3G,4G已经相继推出,但国内的资费价格着实有点不接地气,所以无线wifi无疑是智能机使用最多的.各大软件上.设备商 ...
- CentOS 安装 Docker CE
准备工作 系统要求 Docker CE 支持 64 位版本 CentOS 7,并且要求内核版本不低于 3.10. CentOS 7 满足最低内核的要求,但由于内核版本比较低,部分功能(如 overla ...
- Partition List双色问题链表版
[抄题]: Given a linked list and a value x, partition it such that all nodes less than x come before no ...
- [leetcode]239. Sliding Window Maximum滑动窗口最大值
Given an array nums, there is a sliding window of size k which is moving from the very left of the a ...
- oracle查找特定表的引用
select * from user_source t where upper(t.TEXT) like upper('%table1%') 第二种方法类似于eclipse中的file search ...
- vue小常识小注意
1,跨域携带cookie,加一个拦截器,能后加上request.credentials=true就可以了 Vue.http.interceptors.push(function(request, ne ...