نمایش نتایج 1 تا 9 از 9

نام تاپیک: آرایه Thread ها در Windows Service

  1. #1
    کاربر دائمی
    تاریخ عضویت
    بهمن 1381
    محل زندگی
    اصفهان - ایران
    پست
    289

    Question آرایه Thread ها در Windows Service

    type
    TPingThread = class(TThread)
    private
    { Private declarations }
    protected
    procedure Execute; override;
    procedure Pinging;
    public
    mIP:string;
    mId:Integer;
    constructor Create(Suspend:Boolean;Id:Integer;ip:string);
    destructor Destroy; override;
    end;

    var
    PingServ: TPingServ;
    TikTime:Cardinal;
    MyThread:array of TPingThread;
    PingInterval:Integer;


    سلام
    من در پروژه ای احتیاج دارم یک تعداد کامپیوتر را پینگ کنم و نتیجه را در دیتابیس ذخیره کنم. تعداد کامپیوترها ثابت نیست و لیست آی پی آنها در دیتابیس ذخیره میشود.
    من برای Ping گرفتن یک thread طراحی کرده ام که موقع Create کردن IP و یک Id (که مربوط به دیتابیس است) به آن ارسال می کنم. در این ترد با یک دوره تناوب مثلا یک دقیقه کامپیوتر کلاینت را پینگ می کنم.
    اگر فقط یک بار از Thread استفاده کنم مشکلی نیست. اما من باید thread را به صورت آرایه پویا تعربف کنم و در ابتدای اجرای برنامه با توجه به تعداد رکوردها در دیتابیس تعداد آن را مشخص کنم.
    اتفاق عجیبی که رخ می دهد این است که بعد از چند سیکل (2 یا 3 بار) کم کم داخل thread.mIP و Thread.mId مقادیر بی معنی دیده می شود!!
    آیا نباید کلاس تردها را به صورت آرایه استفاده کرد؟
    ظاهرا مقادیر متغییر ها در تردها تداخل میکند!
    در ضمن برنامه من Windows Service App است

  2. #2
    کاربر دائمی
    تاریخ عضویت
    بهمن 1381
    محل زندگی
    اصفهان - ایران
    پست
    289

    نقل قول: آرایه Thread ها در Windows Service

    این هم سورس برنامه:
    unit untMain;

    interface

    uses
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.SvcMgr, Vcl.Dialogs,
    Data.DB, Data.Win.ADODB, Vcl.ExtCtrls,FunUnit,System.Win.Registry,IdBaseCom ponent,ActiveX,
    IdComponent, IdRawBase, IdRawClient, IdIcmpClient;

    type
    TPingServ = class(TService)
    ADOConnection1: TADOConnection;
    tmrDBConnection: TTimer;
    tmrRefreshSettingFromDB: TTimer;
    procedure RefreshSettingFromDB;
    procedure tmrRefreshSettingFromDBTimer(Sender: TObject);
    procedure tmrDBConnectionTimer(Sender: TObject);
    procedure ServiceAfterInstall(Sender: TService);
    procedure ServiceExecute(Sender: TService);
    procedure ServiceStart(Sender: TService; var Started: Boolean);
    procedure ServiceStop(Sender: TService; var Stopped: Boolean);
    procedure ServiceCreate(Sender: TObject);
    private

    { Private declarations }
    public
    procedure ReadIPList;
    function GetServiceController: TServiceController; override;
    { Public declarations }
    end;

    type
    TPingThread = class(TThread)
    private
    { Private declarations }
    protected
    procedure Execute; override;
    procedure Pinging;
    public
    mIP:string;
    mId:Integer;
    constructor Create(Suspend:Boolean;Id:Integer;ip:string);
    destructor Destroy; override;
    end;

    var
    PingServ: TPingServ;
    TikTime:Cardinal;
    MyThread:array of TPingThread;
    PingInterval:Integer;
    const
    MachineId=0;

    implementation

    {$R *.dfm}

    procedure ServiceController(CtrlCode: DWord); stdcall;
    begin
    PingServ.Controller(CtrlCode);
    end;

    function TPingServ.GetServiceController: TServiceController;
    begin
    Result := ServiceController;
    end;

    procedure TPingThread.Pinging;
    var
    Client:TIdIcmpClient;
    ADOCon:TADOConnection;
    mQuery:TADOQuery;
    DBServer,UserID,Password:string;
    begin
    WriteLog('**'+IntToStr(mId)+' '+mIP);
    Client:=TIdIcmpClient.Create(nil);
    Client.Host:=mIP;
    Client.ReceiveTimeout:=5000;
    Client.Ping;
    ADOCon:=TADOConnection.Create(nil);
    ReadCryptedUserIDAndPasswordToIni(AppPath+'setting s.ini',DBServer,UserID,Password);
    ADOCon.ConnectionString:='Provider=SQLOLEDB.1;Pass word='+Password+';Persist Security Info=True;User ID='+UserID+';Initial Catalog=Smart Factory;Data Source='+DBServer+';Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Use Encryption for Data=False;Tag with column collation when possible=False';
    ADOCon.LoginPrompt:=False;
    mQuery:=TADOQuery.Create(nil);
    mQuery.Connection:=ADOCon;
    try
    ADOCon.Connected:=True;
    if Client.ReplyStatus.BytesReceived <= 0 then begin
    mQuery.SQL.Add('INSERT INTO tblIPPingLog(DT,Id,[Reply],[Time])VALUES(SYSDATETIME(),');
    mQuery.SQL.Add(IntToStr(mId)+',0,50000)');
    end else begin
    mQuery.SQL.Add('INSERT INTO tblIPPingLog(DT,Id,[Reply],[Time])VALUES(SYSDATETIME(),');
    mQuery.SQL.Add(IntToStr(mId)+',1,'+IntToStr(Client .ReplyStatus.MsRoundTripTime)+')');
    end;
    if mQuery.SQL.Count>0 then
    mQuery.ExecSQL;
    except
    On E:Exception Do
    WriteLog(e.Message,'TPingThread.Pinging');
    end;
    mQuery.Free;
    ADOCon.Free;
    Client.Free;
    WriteLog('**++'+IntToStr(mId)+' '+mIP);
    end;

    procedure TPingServ.ReadIPList;
    var
    mQuery:TADOQuery;
    i:Integer;
    ss:string;
    begin
    ADOConnection1.Connected:=True;
    mQuery:=TADOQuery.Create(Self);
    mQuery.Connection:=ADOConnection1;
    mQuery.SQL.Add('SELECT top(1) Id,IP FROM tblIPList ORDER BY Id');
    mQuery.Open;
    if mQuery.RecordCount>0 then begin
    WriteLog(IntToStr(mQuery.RecordCount));
    SetLength(MyThread,mQuery.RecordCount);
    for I := 0 to mQuery.RecordCount-1 do begin
    MyThread[i] := TPingThread.Create(True,mQuery.FieldByName('Id').A sInteger,mQuery.FieldByName('IP').AsString);
    MyThread[i].Start;
    mQuery.Next;
    end;
    //for I := 0 to mQuery.RecordCount-1 do
    // MyThread[i].Start;
    end;
    mQuery.Free;
    end;

    procedure TPingServ.RefreshSettingFromDB;
    var
    mQuery:TADOQuery;
    begin
    if not ADOConnection1.Connected then begin
    tmrDBConnection.Enabled:=True;
    exit;
    end;
    mQuery:=TADOQuery.Create(Self);
    mQuery.Connection:=ADOConnection1;
    try
    mQuery.Connection:=ADOConnection1;
    mQuery.SQL.Text:='SELECT id,Value FROM tblSettings WHERE MachineId='+IntToStr(MachineId);
    mQuery.Open;
    tmrDBConnection.Interval:=VariantToInteger(mQuery. Lookup('Id','20','Value'),10)*1000;
    tmrRefreshSettingFromDB.Interval:=VariantToInteger (mQuery.Lookup('Id','21','Value'),10)*1000;
    PingInterval:=VariantToInteger(mQuery.Lookup('Id', '22','Value'),10)*1000;
    except
    WriteLog('Database Connection Error','TPingServ.RefreshSettingFromDB',True);
    tmrDBConnection.Enabled:=True;
    end;
    mQuery.Free;
    //ReadIPList;
    //tmrRefreshSettingFromDB.Enabled:=True;
    end;

    procedure TPingServ.ServiceAfterInstall(Sender: TService);
    var
    Reg: TRegistry;
    begin
    Reg := TRegistry.Create(KEY_READ or KEY_WRITE);
    try
    Reg.RootKey := HKEY_LOCAL_MACHINE;
    if Reg.OpenKey('\SYSTEM\CurrentControlSet\Services\' + Name, false) then
    begin
    Reg.WriteString('Description', 'Insert IP Ping Log to Database');
    Reg.CloseKey;
    end;
    finally
    Reg.Free;
    end;
    end;

    procedure TPingServ.ServiceCreate(Sender: TObject);
    var
    mQuery:TADOQuery;
    i:Integer;
    begin
    PingInterval:=30000;
    tmrDBConnectionTimer(Self);
    RefreshSettingFromDB;
    end;

    procedure TPingServ.ServiceExecute(Sender: TService);
    var
    i:Integer;
    ss:string;
    begin
    CoInitialize(nil);
    //RefreshSettingFromDB;
    ReadIPList;
    tmrDBConnection.Enabled:=True;
    //tmrRefreshSettingFromDB.Enabled:=True;
    while not Terminated do begin
    sleep(1000);
    ss:='!!!';
    for I := Low(MyThread) to High(MyThread) do
    ss:=ss+IntToStr(MyThread[i].mId)+' ';
    WriteLog(ss);
    //for I := Low(MyThread) to High(MyThread) do
    // MyThread.Start;
    ServiceThread.ProcessRequests(False);// wait for termination
    end;
    CoUninitialize;
    end;

    procedure TPingServ.ServiceStart(Sender: TService; var Started: Boolean);
    begin
    WriteLog('Service Started','Service',True);
    TikTime:=GetTickCount;
    end;

    procedure TPingServ.ServiceStop(Sender: TService; var Stopped: Boolean);
    begin
    WriteLog('Service Stoped','Service',True);
    end;

    procedure TPingServ.tmrDBConnectionTimer(Sender: TObject);
    var
    DBServer,UserID,Password:string;
    begin
    tmrDBConnection.Enabled:=False;
    if ADOConnection1.Connected then
    ADOConnection1.Close;
    ReadCryptedUserIDAndPasswordToIni(AppPath+'setting s.ini',DBServer,UserID,Password);
    ADOConnection1.ConnectionString:='Provider=SQLOLED B.1;Password='+Password+';Persist Security Info=True;User ID='+UserID+';Initial Catalog=Smart Factory;Data Source='+DBServer+';Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Use Encryption for Data=False;Tag with column collation when possible=False';
    try
    ADOConnection1.Connected:=True;
    except
    WriteLog('Database Connection Error','TPingServ.tmrDBConnectionTimer',True);
    tmrDBConnection.Enabled:=True;
    end;
    end;

    procedure TPingServ.tmrRefreshSettingFromDBTimer(Sender: TObject);
    begin
    RefreshSettingFromDB;
    end;

    { TPingThread }

    constructor TPingThread.Create(Suspend: Boolean; Id: Integer; ip: string);
    begin
    inherited Create(true);
    FreeOnTerminate := True;
    mIP:=ip;
    mId:=Id;
    end;

    destructor TPingThread.Destroy;
    begin
    inherited;
    end;

    procedure TPingThread.Execute;
    begin
    while not Terminated do begin
    WriteLog('Start Pinging Id='+IntToStr(mId)+mIP);
    Pinging;
    WriteLog('End Pinging Id='+IntToStr(mId)+mIP+'Interval='+IntToStr(PingIn terval));
    Sleep(PingInterval);
    end;
    end;

    end.


    اگر خط 116 را به صورت زیر تغییر بدهم نتایج عجیب و غریبی به دست می آید:
    mQuery.SQL.Add('SELECT Id,IP FROM tblIPList ORDER BY Id');

  3. #3

    نقل قول: آرایه Thread ها در Windows Service

    نقل قول نوشته شده توسط masoode مشاهده تاپیک
    type
    TPingThread = class(TThread)
    private
    { Private declarations }
    protected
    procedure Execute; override;
    procedure Pinging;
    public
    mIP:string;
    mId:Integer;
    constructor Create(Suspend:Boolean;Id:Integer;ip:string);
    destructor Destroy; override;
    end;

    var
    PingServ: TPingServ;
    TikTime:Cardinal;
    MyThread:array of TPingThread;
    PingInterval:Integer;


    سلام
    من در پروژه ای احتیاج دارم یک تعداد کامپیوتر را پینگ کنم و نتیجه را در دیتابیس ذخیره کنم. تعداد کامپیوترها ثابت نیست و لیست آی پی آنها در دیتابیس ذخیره میشود.
    من برای Ping گرفتن یک thread طراحی کرده ام که موقع Create کردن IP و یک Id (که مربوط به دیتابیس است) به آن ارسال می کنم. در این ترد با یک دوره تناوب مثلا یک دقیقه کامپیوتر کلاینت را پینگ می کنم.
    اگر فقط یک بار از Thread استفاده کنم مشکلی نیست. اما من باید thread را به صورت آرایه پویا تعربف کنم و در ابتدای اجرای برنامه با توجه به تعداد رکوردها در دیتابیس تعداد آن را مشخص کنم.
    اتفاق عجیبی که رخ می دهد این است که بعد از چند سیکل (2 یا 3 بار) کم کم داخل thread.mIP و Thread.mId مقادیر بی معنی دیده می شود!!
    آیا نباید کلاس تردها را به صورت آرایه استفاده کرد؟
    ظاهرا مقادیر متغییر ها در تردها تداخل میکند!
    در ضمن برنامه من Windows Service App است
    Thread synchronization رو یک جستجو بکنید .
    در ثانی کدتون رو با Parallel Programming Library پیاده سازی کنید.

  4. #4
    کاربر دائمی
    تاریخ عضویت
    بهمن 1381
    محل زندگی
    اصفهان - ایران
    پست
    289

    نقل قول: آرایه Thread ها در Windows Service

    نقل قول نوشته شده توسط pe32_64 مشاهده تاپیک
    Thread synchronization رو یک جستجو بکنید .
    در ثانی کدتون رو با Parallel Programming Library پیاده سازی کنید.
    یعنی به نظر شما با یک دستکاری یا تغییر جزئی کارم راه نمی افته؟
    آخه برای یک ترد هیچ مشکلی نداره اما وقتی 2 تا یا بیشتر می شه انگار فضای اختصاص داده شده حافظه قاطی پاطی می شه!

  5. #5

    نقل قول: آرایه Thread ها در Windows Service

    منظورتون از "مقادیر بی معنی" چیه ؟ نمونه قرار بدید
    چند نکته در مورد کد :
    زمانی که یک شی رو Create می کنید بهتره از فرمت زیر استفاده کنید تا مطمئن باشید که اون شی حتما آزاد میشه :

    mQuery := TADOQuery.Create(nil);
    try
    try
    ...
    except
    ...
    end;
    finally
    mQuery.Free;
    end;

    در حال حاضر اگر در بین کار خطایی رخ بده حتما Memory-Leak ایجاد میشه و برای برنامه ای که به صورت Service و دایما در حال اجراست وجود Memory-Leak حتما مشکل ساز میشه
    برای Object هایی که در Thread استفاده می کنید بهتره که اونها رو در Constructor مربوط به Thread بسازید و در Destructor آزاد کنید
    نیاز نیست هر بار که حلقه داخل Thread اجرا میشه دوباره Connect بشید به بانک اطلاعاتی، اگر در Constructor مربوط به Thread اشیا Connection و Query و IdTCPClient رو بسازید ، می تونید در ابتدای متد Execute به بانک اطلاعاتی وصل بشید و در داخل حلقه فقط چک کنید اگر ارتباط قطع شده بود دوباره متصل بشید
    قبل از حلقه ای که برای ساخت Thread نوشتید از دستور mQuery.First استفاده کنید تا اطمینان داشته باشید که حلقه از رکورد اول شروع میشه، در حالت کلی برای پیمایش یک DataSet بهتره که از حلقه While و بررسی TDataSet.Eof استفاده بشه
    ...
    چند نمونه از خروجی برنامه بذارید تا بررسی بشه

  6. #6
    کاربر دائمی
    تاریخ عضویت
    بهمن 1381
    محل زندگی
    اصفهان - ایران
    پست
    289

    نقل قول: آرایه Thread ها در Windows Service

    نقل قول نوشته شده توسط Mahmood_M مشاهده تاپیک
    منظورتون از "مقادیر بی معنی" چیه ؟ نمونه قرار بدید
    چند نکته در مورد کد :
    زمانی که یک شی رو Create می کنید بهتره از فرمت زیر استفاده کنید تا مطمئن باشید که اون شی حتما آزاد میشه :

    mQuery := TADOQuery.Create(nil);
    try
    try
    ...
    except
    ...
    end;
    finally
    mQuery.Free;
    end;

    در حال حاضر اگر در بین کار خطایی رخ بده حتما Memory-Leak ایجاد میشه و برای برنامه ای که به صورت Service و دایما در حال اجراست وجود Memory-Leak حتما مشکل ساز میشه
    برای Object هایی که در Thread استفاده می کنید بهتره که اونها رو در Constructor مربوط به Thread بسازید و در Destructor آزاد کنید
    نیاز نیست هر بار که حلقه داخل Thread اجرا میشه دوباره Connect بشید به بانک اطلاعاتی، اگر در Constructor مربوط به Thread اشیا Connection و Query و IdTCPClient رو بسازید ، می تونید در ابتدای متد Execute به بانک اطلاعاتی وصل بشید و در داخل حلقه فقط چک کنید اگر ارتباط قطع شده بود دوباره متصل بشید
    قبل از حلقه ای که برای ساخت Thread نوشتید از دستور mQuery.First استفاده کنید تا اطمینان داشته باشید که حلقه از رکورد اول شروع میشه، در حالت کلی برای پیمایش یک DataSet بهتره که از حلقه While و بررسی TDataSet.Eof استفاده بشه
    ...
    چند نمونه از خروجی برنامه بذارید تا بررسی بشه
    ممنون از وقتی گذاشتید. مواردی فرمودید را حتماً برای بهینه شدن اعمال خواهم کرد اما فکر نکنم مشکلم با آنها حل بشه!

    ss:='!!!';
    for I := Low(MyThread) to High(MyThread) do
    ss:=ss+IntToStr(MyThread[i].mId)+' ';
    WriteLog(ss);

    در سطر 197 تا 200 هر یک ثانیه یک بار وضعیت متغیر MyThread[i].mId (و MyThread[i].mIP که اینجا پاکش کرده ام) را در یک فایل log میگیرم. من برای تست برنامه در دیتابیس 8 آدرس آی پی ثبت کرده ام که آی دی های آنها فعلا از 1 تا 8 است. نتیجه فایل log در حالتی که فقط یک ip را میخواند مشکلی ندارد و همیشه می نویسد

    1397/10/16 17:09 !!!1
    1397/10/16 17:09 !!!1
    1397/10/16 17:09 !!!1
    1397/10/16 17:09 !!!1
    1397/10/16 17:09 !!!1
    1397/10/16 17:09 !!!1
    1397/10/16 17:09 !!!1
    1397/10/16 17:09 !!!1
    1397/10/16 17:09 !!!1
    1397/10/16 17:09 !!!1
    1397/10/16 17:09 !!!1
    1397/10/16 17:09 !!!1
    1397/10/16 17:09 !!!1
    1397/10/16 17:09 !!!1
    1397/10/16 17:09 !!!1

    اما وقتی 8 تایی میشود نتایج متفاوت اما معمولا این جوری میشود:

    1397/10/16 15:53 !!!1 2 3 4 5 6 7 8
    1397/10/16 15:54 !!!3145778 2 3 4 5 6 7 0
    1397/10/16 15:54 !!!3145778 2 3 4 5 6 7 0
    1397/10/16 15:54 !!!3145778 2 3 7929977 46 6 7 0
    1397/10/16 15:54 !!!3145778 2 3 7929977 46 6 7 0
    1397/10/16 15:54 !!!3145778 2 3 7929977 46 6 7 0
    1397/10/16 15:54 !!!3145778 2 3 7929977 46 6 7 0
    1397/10/16 15:54 !!!3145778 2 3 7929977 46 6 7 0
    1397/10/16 15:54 !!!3145778 2 3 7929977 46 6 7 0
    1397/10/16 15:54 !!!3145778 2 3 7929977 46 6 7 0
    1397/10/16 15:54 !!!3145778 2 3 7929977 46 6 7 0
    1397/10/16 15:54 !!!3145778 2 3 7929977 46 6 7 0
    1397/10/16 15:54 !!!3145778 2 3 7929977 46 6 7 0
    آخرین ویرایش به وسیله masoode : دوشنبه 17 دی 1397 در 14:55 عصر

  7. #7

    نقل قول: آرایه Thread ها در Windows Service

    عرض کردم که برای حل مشکل باید نمونه خروجی رو قرار بدید، مواردی که گفته شد برای جلوگیری از مشکلات دیگه ست
    سورس دستور WriteLog رو قرار بدید، احتمالا مشکل در این دستور ایجاد میشه
    از این دستور در چند ترد به صورت همزمان استفاده کردید، بنابراین باید Synchronization رو رعایت کنید، مثلا باید از CriticalSection استفاده کنید
    راه درست برای نوشتن Log اینه که یک صف ( مثلا یک StringList ) از خطوطی که باید در لاگ نوشته بشه داشته باشید و هر ترد فقط متن مورد نظرش رو در داخل این صف قرار بده و در یک ترد جداگانه این لیست پیمایش بشه و در فایل Log نوشته بشه. برای ثبت متن Log از درون هر ترد باز باید از CriticalSection استفاده کنید یا اینکه از کلاسهای Thread-Safe مثل TThreadList استفاده کنید که مخصوص همین کار ایجاد شدن و به صورت داخلی Synchronization رو مدیریت می کنن

  8. #8
    کاربر دائمی
    تاریخ عضویت
    بهمن 1381
    محل زندگی
    اصفهان - ایران
    پست
    289

    نقل قول: آرایه Thread ها در Windows Service

    نقل قول نوشته شده توسط Mahmood_M مشاهده تاپیک
    عرض کردم که برای حل مشکل باید نمونه خروجی رو قرار بدید، مواردی که گفته شد برای جلوگیری از مشکلات دیگه ست
    سورس دستور WriteLog رو قرار بدید، احتمالا مشکل در این دستور ایجاد میشه
    از این دستور در چند ترد به صورت همزمان استفاده کردید، بنابراین باید Synchronization رو رعایت کنید، مثلا باید از CriticalSection استفاده کنید
    راه درست برای نوشتن Log اینه که یک صف ( مثلا یک StringList ) از خطوطی که باید در لاگ نوشته بشه داشته باشید و هر ترد فقط متن مورد نظرش رو در داخل این صف قرار بده و در یک ترد جداگانه این لیست پیمایش بشه و در فایل Log نوشته بشه. برای ثبت متن Log از درون هر ترد باز باید از CriticalSection استفاده کنید یا اینکه از کلاسهای Thread-Safe مثل TThreadList استفاده کنید که مخصوص همین کار ایجاد شدن و به صورت داخلی Synchronization رو مدیریت می کنن
    کد writelog را خیلی وقت پیش نوشته ام و توی یک Unit دیگر است این هم کدش:

    procedure WriteLog(eDesc:string; eLocation: String=''; UseMiladiDate:boolean=False);
    var
    Y,M,D:Word;
    Dir,tFileName,LineL:String;
    tFile:TextFile;
    begin
    if not UseMiladiDate then
    DecodeDateShamsi(Y,M,D)
    else
    DecodeDate(Now,Y,M,D);
    Dir:=AppPath+FIX_STR_LEN(IntToStr(Y),4)+'\';
    if not DirectoryExists(Dir) then CreateDir(Dir);
    Dir:=Dir+FIX_STR_LEN(IntToStr(M),2)+'\';
    if not DirectoryExists(Dir) then CreateDir(Dir);
    tFileName:=Dir+FIX_STR_LEN(IntToStr(D),2)+'.log';
    AssignFile(tFile,tFileName);
    if not FileExists(tFileName) then
    Rewrite(tFile)
    else
    Append(tFile);
    if eLocation<>'' then
    LineL:=FIX_STR_LEN(IntToStr(Y),4)+'/'+FIX_STR_LEN(IntToStr(M),2)+'/'+FIX_STR_LEN(IntToStr(D),2)+' '+FormatDateTime('HH:MM',Time)+' '+eDesc+' in '+eLocation
    else
    LineL:= FIX_STR_LEN(IntToStr(Y),4)+'/'+FIX_STR_LEN(IntToStr(M),2)+'/'+FIX_STR_LEN(IntToStr(D),2)+' '+FormatDateTime('HH:MM',Time)+' '+eDesc;
    Writeln(tFile,LineL);
    CloseFile(tFile);
    end;

    به نظر شما اگر اشکال از Log باشه، از CodeSite هم استفاده کنم ممکنه این مشکل پیش بیاد؟

  9. #9
    کاربر دائمی
    تاریخ عضویت
    بهمن 1381
    محل زندگی
    اصفهان - ایران
    پست
    289

    نقل قول: آرایه Thread ها در Windows Service

    با راهنمایی شما امروز یک چیز جدید یاد گرفتم
    عجب چیزیه این CriticalSection
    جالبه قبلا خود شما برای من توضیح داده بودید اما من فراموش کرده بودم
    https://barnamenevis.org/showthread.p...riticalSection
    فعلا برای اینکه کارم راه بیوفته لاگ گرفتن را حدف کردم. مشکلم حل شد.
    از CodeSite قبلا خیلی کم برای تست استفاده کرده ام و یک کم بلدم باهاش کار کنم این هم لینک آموزشش:
    http://www.drbob42.com/examines/examinD2.htm
    البته قبلا یک آموزش فارسی کامل دیده بودم که پیداش نکردم.
    حالا مشکل اینجاست که دستورات CodeSite را که در ترد استفاده میکنم کار نمی کند!
    procedure TPingThread.Pinging;
    var
    Client:TIdIcmpClient;
    ADOCon:TADOConnection;
    mQuery:TADOQuery;
    DBServer,UserID,Password:string;
    begin
    CodeSite.EnterMethod('TPingThread.Pinging');
    CodeSite.Send('Id=',mid);
    CodeSite.Send('IP=',mIP);
    //WriteLog('**'+IntToStr(mId)+' '+mIP);
    Client:=TIdIcmpClient.Create(nil);
    Client.Host:=mIP;
    Client.ReceiveTimeout:=5000;
    Client.Ping;
    ADOCon:=TADOConnection.Create(nil);
    ReadCryptedUserIDAndPasswordToIni(AppPath+'setting s.ini',DBServer,UserID,Password);
    ADOCon.ConnectionString:='Provider=SQLOLEDB.1;Pass word='+Password+';Persist Security Info=True;User ID='+UserID+';Initial Catalog=Smart Factory;Data Source='+DBServer+';Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Use Encryption for Data=False;Tag with column collation when possible=False';
    ADOCon.LoginPrompt:=False;
    mQuery:=TADOQuery.Create(nil);
    mQuery.Connection:=ADOCon;
    try
    ADOCon.Connected:=True;
    if Client.ReplyStatus.BytesReceived <= 0 then begin
    mQuery.SQL.Add('INSERT INTO tblIPPingLog(DT,Id,[Reply],[Time])VALUES(SYSDATETIME(),');
    mQuery.SQL.Add(IntToStr(mId)+',0,50000)');

    end else begin
    mQuery.SQL.Add('INSERT INTO tblIPPingLog(DT,Id,[Reply],[Time])VALUES(SYSDATETIME(),');
    mQuery.SQL.Add(IntToStr(mId)+',1,'+IntToStr(Client .ReplyStatus.MsRoundTripTime)+')');
    end;
    CodeSite.Send(mQuery.SQL.Text);
    if mQuery.SQL.Count>0 then
    mQuery.ExecSQL;
    except
    //On E:Exception Do
    // WriteLog(e.Message,'TPingThread.Pinging');
    end;
    mQuery.Free;
    ADOCon.Free;
    Client.Free;
    //WriteLog('**++'+IntToStr(mId)+' '+mIP);
    CodeSite.ExitMethod('TPingThread.Pinging');

تاپیک های مشابه

  1. آموزش ساخت Windows Service و Windows EventLog با #C . (ویدیو آموزشی)
    نوشته شده توسط hoseineghbal در بخش C#‎‎
    پاسخ: 7
    آخرین پست: سه شنبه 25 شهریور 1393, 12:21 عصر
  2. مشکل نصب Windows Service در Windows 7 (ویندوز سون)
    نوشته شده توسط Happy_davood در بخش C#‎‎
    پاسخ: 1
    آخرین پست: چهارشنبه 09 تیر 1389, 22:12 عصر
  3. مشكل با Windows Service
    نوشته شده توسط powerboy2988 در بخش C#‎‎
    پاسخ: 2
    آخرین پست: سه شنبه 28 مهر 1388, 14:54 عصر
  4. عدم نمایش Windows service در سرویس های Windows
    نوشته شده توسط Behsharp در بخش C#‎‎
    پاسخ: 2
    آخرین پست: دوشنبه 23 مهر 1386, 12:12 عصر

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •