在线程的create重载中,为private的变量赋值总是出错? ( 积分: 100 )

  • 主题发起人 主题发起人 RollingStone
  • 开始时间 开始时间
R

RollingStone

Unregistered / Unconfirmed
GUEST, unregistred user!
各位辛苦,我的线程单元代码如下:
unit Unit1;
interface
uses
Classes, StdCtrls, SConnect;
type
TMyThread1 = class(TThread)
private
{ Private declarations }
FNo: Integer;
FStr: String;
FILow, FIHigh, MyI: Integer;
protected
procedure sckOpen;
procedure Execute;
override;
public
constructor Create(No: Integer;
str: String;
ILow, IHigh: Integer);
end;

implementation
{ Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example,
Synchronize(UpdateCaption);
and UpdateCaption could look like,
procedure TMyThead1.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end;
}
{ TMyThead1 }
uses SysUtils, Scan;
constructor TMyThread1.Create(No: Integer;
str: String;
ILow, IHigh: Integer);
begin
Self.FNo:= No;
Self.FStr:= str;
Self.FILow:= ILow;
Self.FIHigh:= IHigh;
Inherited Create(False);
end;
........
我的主程序中调用线程的过程如下:
....
procedure TMainForm.Button1Click(Sender: TObject);
begin
MyThread1.Create(1, edtStartIP.Text+'.'+ edt1.Text+ '.', 1, 63);
MyThread1.Create(2, edtStartIP.Text+'.'+ edt1.Text+ '.', 64, 127);
end;
.......
我使用的是delphi7,程序的意思是对***.***.***.1----***.***.***.127的地址段进行扫描,通过TSocketConnection进行扫描。
 
各位辛苦,我的线程单元代码如下:
unit Unit1;
interface
uses
Classes, StdCtrls, SConnect;
type
TMyThread1 = class(TThread)
private
{ Private declarations }
FNo: Integer;
FStr: String;
FILow, FIHigh, MyI: Integer;
protected
procedure sckOpen;
procedure Execute;
override;
public
constructor Create(No: Integer;
str: String;
ILow, IHigh: Integer);
end;

implementation
{ Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example,
Synchronize(UpdateCaption);
and UpdateCaption could look like,
procedure TMyThead1.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end;
}
{ TMyThead1 }
uses SysUtils, Scan;
constructor TMyThread1.Create(No: Integer;
str: String;
ILow, IHigh: Integer);
begin
Self.FNo:= No;
Self.FStr:= str;
Self.FILow:= ILow;
Self.FIHigh:= IHigh;
Inherited Create(False);
end;
........
我的主程序中调用线程的过程如下:
....
procedure TMainForm.Button1Click(Sender: TObject);
begin
MyThread1.Create(1, edtStartIP.Text+'.'+ edt1.Text+ '.', 1, 63);
MyThread1.Create(2, edtStartIP.Text+'.'+ edt1.Text+ '.', 64, 127);
end;
.......
我使用的是delphi7,程序的意思是对***.***.***.1----***.***.***.127的地址段进行扫描,通过TSocketConnection进行扫描。
 
出错现象描述:
1)编译运行正常;
2)一点击按钮,开始执行 TMainForm.Button1Click(Sender: TObject);,程序就报错:“Project Scanner.exe raised exception class EAccessViolation with
message 'Access violation at address 00468956 in module 'Scanner.exe'. Write of
address 00000040'.Process stopped.Use Step or Run to continue.”,同时编译器指
示constructor TMyThread1.Create(No: Integer;
str: String;
ILow, IHigh: Integer);
中的Self.FNo:= No;出错。
 
线程单元的完整代码如下:
unit Unit1;
interface
uses
Classes, StdCtrls, SConnect;
type
TMyThread1 = class(TThread)
private
{ Private declarations }
FNo: Integer;
FStr: String;
FILow, FIHigh, MyI: Integer;
protected
procedure sckOpen;
procedure Execute;
override;
public
constructor Create(No: Integer;
str: String;
ILow, IHigh: Integer);
end;

implementation
{ Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example,
Synchronize(UpdateCaption);
and UpdateCaption could look like,
procedure TMyThead1.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end;
}
{ TMyThead1 }
uses SysUtils, Scan;
constructor TMyThread1.Create(No: Integer;
str: String;
ILow, IHigh: Integer);
begin
Self.FNo:= No;
Self.FStr:= str;
Self.FILow:= ILow;
Self.FIHigh:= IHigh;
Inherited Create(False);
end;

procedure TMyThread1.sckOpen;
var
IngIP: String;
begin
IngIP:= FStr+ IntToStr(MyI);
case FNo of
1: begin
MainForm.Edit1.Text:= IngIP;
MainForm.sck1.Address:= IngIP;
try
MainForm.sck1.Open;
except
end;
if MainForm.sck1.Connected then
MainForm.Memo1.Lines.Append(IngIP);
end;
2: begin
MainForm.Edit2.Text:= IngIP;
MainForm.sck2.Address:= IngIP;
try
MainForm.sck2.Open;
except
end;
if MainForm.sck2.Connected then
MainForm.Memo1.Lines.Append(IngIP);
end;
end;
end;

procedure TMyThread1.Execute;
var
i: Integer;
begin
{ Place thread code here }
FreeOnTerminate:= True;
Priority:= tpHighest;
for i:=FILow to FIHighdo
begin
if Terminated then
Break;
MyI:= i;
Synchronize(sckOpen);
end;
end;

end.
 
主程序的完整代码如下:
unit Scan;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, DBClient, MConnect, SConnect, StdCtrls, ExtCtrls;
type
TMainForm = class(TForm)
edtStartIP: TEdit;
Button1: TButton;
edtEndIP: TEdit;
Memo1: TMemo;
sck1: TSocketConnection;
Label1: TLabel;
Label2: TLabel;
btnTrans: TButton;
diagSave: TSaveDialog;
edt1: TEdit;
edt2: TEdit;
Memo2: TMemo;
Timer1: TTimer;
sck2: TSocketConnection;
Edit1: TEdit;
Edit2: TEdit;
procedure btnTransClick(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
MainForm: TMainForm;
implementation
uses Unit1, Unit2;
{$R *.dfm}

var
MyThread1, MyThread2: TMyThread1;
procedure TMainForm.btnTransClick(Sender: TObject);
begin
if diagSave.Execute then
Memo1.Lines.SaveToFile(diagSave.FileName);
end;

procedure TMainForm.Button1Click(Sender: TObject);
begin
MyThread1.Create(1, edtStartIP.Text+'.'+ edt1.Text+ '.', 1, 63);
MyThread1.Create(2, edtStartIP.Text+'.'+ edt1.Text+ '.', 64, 127);
end;

end.
 
把变量改为PUBLIC.
 
to: piaosjy
我刚才按照你说的做了,把那几个变量从private挪到public下面,但是问题依旧。。。郁闷!
我实在看不出程序的错误在哪里阿
期待。。。
 
不好意思,刚刚我搞错了
 
to piaosiy:
非常感谢你提供的连接,但是我的原因应该和Another_eYes说到的那个情况不一样:
因为我的程序还没有进行到对主线程的VCL进行同步的时候就出错了,刚刚重载线程的Create就出错了,并且只是给private下面的变量赋值就出错了。
真是让人想不通啊!
 
昨天我后面也发现了是不同,多线程我也不太会,接触的不多.我那个程序使用的是CreateThread创建的线程其中有线程属性(用于在NT下进行线程的安全属性设置,在9X下无效),堆栈大小,起始地址,参数,创建标志(用于设置线程创建时的状态),线程ID等参数,我不太清楚你这种继承过来的要否要这种参数,但你这种子线程可能会引起和我那边一样的错误.
 
其实是一个很简单的问题,是你的代码写错了,我开始也没有发现,呵。
procedure TMainForm.Button1Click(Sender: TObject);
begin
MyThread1.Create(1, edtStartIP.Text+'.'+ edt1.Text+ '.', 1, 63);
MyThread1.Create(2, edtStartIP.Text+'.'+ edt1.Text+ '.', 64, 127);
end;
建立线程对象出错。应为: MyThread1 := TMyThread1.Create(1, edtStartIP.Text+'.'+ edt1.Text+ '.', 1, 63);

老兄,你可要给点分我啊。我专家分是零分。。。。
 
yes.
但是重载为什么不用加overload呢?是不是类继承下来就可以不用加?
 
在overload前面加一个reintroduce关键字就可以了
 
多人接受答案了。
 
后退
顶部