首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > .NET >

问高人,线程或者单元之间传递对象数组,采用全局变量的形式,如何样才能不需要单元之间互相包含

2012-02-14 
问高人,线程或者单元之间传递对象数组,采用全局变量的形式,怎么样才能不需要单元之间互相包含?问题如题,具

问高人,线程或者单元之间传递对象数组,采用全局变量的形式,怎么样才能不需要单元之间互相包含?
问题如题,具体代码如下:

主线程:

unit   Unit1;

interface

uses
    Windows,   Messages,   SysUtils,   Variants,   Classes,   Graphics,   Controls,   Forms,
    Dialogs,   StdCtrls,SyncObjs;

type
    TForm1   =   class(TForm)
        Memo1:   TMemo;
        Button1:   TButton;
        Memo2:   TMemo;
        Memo3:   TMemo;
        procedure   Button1Click(Sender:   TObject);
        procedure   FormClose(Sender:   TObject;   var   Action:   TCloseAction);
    private
        {   Private   declarations   }
    public
        {   Public   declarations   }
        S:   Array   of   string;
        cs:   TRTLCriticalSection;
        procedure   WriteLog(msg:   string);
    end;

var
    Form1:   TForm1;


implementation
uses   unit2,unit3;
{$R   *.dfm}

procedure   TForm1.Button1Click(Sender:   TObject);
var
        one:   Threadone;
        Two:   ThreadTwo;
begin
        InitializeCriticalSection(cs);
        one:=Threadone.create(cs,s,0);
        Two:=ThreadTwo.create(cs,s,0);
end;

procedure   TForm1.WriteLog(msg:   string);
var
        sFile:   textFile;
        AppPath:   string;
        sDayStr:   string;
        sFileName:   string;
        FindResult:   integer;
        iFileCount:   integer;
        MinFileName:   string;
        sr:   TSearchRec;
begin
        //判断日志目录是否存在
        AppPath:=getCurrentDir;
        if   not   DirectoryExists(AppPath   +   '\Login ')     then
                MkDir( 'Login ');   //如果目录不存在,则建立目录
        sDayStr:=FormatDateTime( 'YYYYMMDD ',Now());

        sFileName:=AppPath   +   '\Login\ '   +   sDayStr   +   '.log ';
        Assignfile(sfile,sFileName);
        try
                if   FileExists(sFileName)   then       //判断文件是否存在
                        Append(sFile)
                else
                        ReWrite(sFile);
        except
                ReWrite(sFile);
        end;
        writeln(sfile,FormatDateTime( 'YYYY-MM-DD   hh:nn:ss ',Now())   +   '       '   +   msg);


        closefile(sFile);

        //判断日志文件是否超过20个,如果超过,则删除最小日期的文件
        iFileCount:=0;
        FindResult:=FindFirst(AppPath   +   '\Login\*.log ',faAnyFile,sr);
        try
                while   FindResult=0   do
                begin
                        iFileCount:=iFileCount   +   1;
                        if   iFileCount=1   then
                                MinFileName:=sr.Name
                        else
                                if   MinFileName> sr.Name   then
                                        MinFileName:=sr.Name;
                        FindResult:=FindNext(sr);
                end;
        finally
                FindClose(sr);
        end;
        if   iFileCount> 2   then
                DeleteFile(AppPath   +   '\Login\ '   +   MinFileName);
end;

procedure   TForm1.FormClose(Sender:   TObject;   var   Action:   TCloseAction);
begin
        DeleteCriticalSection(cs);
end;

end.

线程1:
unit   Unit2;

interface

uses
    Classes,SysUtils,Windows;

type
    Threadone   =   class(TThread)
    private
        {   Private   declarations   }
        s:   Array   of   string;
        cs:   TRTLCriticalSection;
        iCount:   integer;
    protected
        procedure   Execute;   override;
        procedure   writes;
    public
        Constructor   Create(css:   TRTLCriticalSection;   ss:   pointer;   Count:   integer);
    end;

implementation
uses   unit1;
{   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   Threadone.UpdateCaption;
        begin
            Form1.Caption   :=   'Updated   in   a   thread ';
        end;   }



{   Threadone   }
Constructor   ThreadOne.Create(css:   TRTLCriticalSection;   ss:   pointer;   Count:   integer);
begin
        cs:=css;
        iCount:=Count;
        SetLength(s,iCount);
        s:=ss;
        inherited   Create(False);
end;

procedure   Threadone.Execute;
var
        str:   string;
        index:   integer;
begin
    {   Place   thread   code   here   }
        index:=1;
        while   true   do
        begin
                try
                        if   index=1   then   str:= 'a ';
                        if   index=2   then   str:= 'b ';
                        if   index=3   then   str:= 'c ';
                        if   index=4   then   str:= 'd ';
                        if   index=5   then   str:= 'e ';

                        EnterCriticalSection(CS);

                        setLength(Form1.s,Length(Form1.s)+1);
                        form1.S[Length(form1.s)-1]:=str;
                        {
                        Setlength(s,Length(s)+1);
                        s[Length(s)-1]:=str;
                        }
                        LeaveCriticalSection(CS);
                        if   index=5   then
                                index:=1
                        else
                                Index:=index+1;
                        Synchronize(writes);
                        form1.writelog( 'ssss ');

                        sleep(1000);
                except   on   e:exception   do
                        form1.writelog(e.Message);
                end;
        end;


end;

procedure   Threadone.writes   ;
begin
        //form1.Memo2.Lines.Add(s[iCount]);
        form1.Memo2.Lines.Add(form1.s[iCount]);
end;


end.

线程2:
unit   Unit3;

interface

uses
    Classes,Windows;

type
    ThreadTwo   =   class(TThread)
    private
        {   Private   declarations   }
        s:   Array   of   string;
        iCount:   integer;
        cs:   TRTLCriticalSection;
        procedure   writes;
    protected
        procedure   Execute;   override;
    public
        Constructor   Create(css:   TRTLCriticalSection;   ss:   Pointer;   count:   integer);
    end;

implementation
uses   unit1;
{   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   ThreadTwo.UpdateCaption;
        begin
            Form1.Caption   :=   'Updated   in   a   thread ';
        end;   }

{   ThreadTwo   }
Constructor   ThreadTwo.Create(css:   TRTLCriticalSection;   ss:   Pointer;   count:   integer);
begin
        cs:=css;
        iCount:=Count;
        SetLength(s,iCount);
        s:=ss;
        inherited   Create(False);
end;

procedure   ThreadTwo.Execute;
var
        tmpArray:   array   of   string;
        i:   integer;
begin
        {   Place   thread   code   here   }
        while   true   do
        begin
                {
                iCount:=Length(s);
                if   iCount> 0   then
                begin
                        Synchronize(writes);
                        EnterCriticalSection(cs);
                        setlength(tmpArray,iCount-1);
                        for   i:=0   to   iCount-1   do
                        begin
                                tmpArray[i]:=s[i+1];


                        end;
                        SetLength(s,Length(tmpArray));
                        for   i:=0   to   Length(tmpArray)-1   do
                        begin
                                s[i]:=tmpArray[i];
                        end;
                        LeaveCriticalSection(cs);
                end;
                }
                if   Length(Form1.S)> 0   then
                begin
                        Synchronize(writes);
                        EnterCriticalSection(cs);
                        setlength(tmpArray,Length(Form1.s)-1);
                        for   i:=1   to   Length(Form1.s)-1   do
                        begin
                                tmpArray[i-1]:=Form1.s[i];
                        end;
                        if   Length(tmpArray)> 0   then
                        begin
                                SetLength(s,Length(tmpArray)-1);
                                for   i:=0   to   Length(tmpArray)-1   do
                                begin
                                        Form1.s[i]:=tmpArray[i];
                                end;
                        end
                        else
                        begin
                                SetLength(Form1.s,0);
                        end;

                        LeaveCriticalSection(cs);
                end;
                sleep(100);


        end;

end;

procedure   ThreadTwo.writes;
begin
        form1.Memo1.Lines.Add(form1.s[0]);
end;

end.
程序的本意就是线程1向一个数组中添加元素,线程2从这个数组中取出第一个元素显示在主线程的界面上。
目前采用的办法是使用单元之间互相包含的方式实现的。能不能采取参数传递的方式实现呢?

[解决办法]
type
//改写成这样
TSomeThreadA= class(TThread)
begin
..........
end;

//改写成这样
TSomeThreadB= class(TThread)
begin
..........
end;


TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
Memo2: TMemo;
Memo3: TMemo;
procedure Button1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
S: Array of string;
cs: TRTLCriticalSection;
procedure WriteLog(msg: string);
end;
[解决办法]
都放在一个单元里面好了.
[解决办法]
定义一个单元unit4, 将S: Array of string;
cs: TRTLCriticalSection;放在这个unit4单元中,所有的单元中的S和cs都可以赋值得到。

热点排行