Multithreading 释放和重用线程的正确方法
我使用的是DelphiXe2,我的应用程序用于通知twitter/rss中的新记录。在我的应用程序中,我每秒使用2个线程从twitter和rss获取一些数据 代码如下: 类型部分:Multithreading 释放和重用线程的正确方法,multithreading,delphi,deadlock,reusability,Multithreading,Delphi,Deadlock,Reusability,我使用的是DelphiXe2,我的应用程序用于通知twitter/rss中的新记录。在我的应用程序中,我每秒使用2个线程从twitter和rss获取一些数据 代码如下: 类型部分: TWarframeEvent=record GUID: String; EventType: Byte; // 0 = unknown; 1 = alert; 2 = invasion; 3 = infestation Planet: String; Mission: String
TWarframeEvent=record
GUID: String;
EventType: Byte; // 0 = unknown; 1 = alert; 2 = invasion; 3 = infestation
Planet: String;
Mission: String;
EventDate: TDateTime;
Time: Integer;
RewardCredits: LongWord;
RewardOther: String;
RewardOtherAmount: Integer;
Notified: Boolean;
ItemIndex: Integer;
Hidden: Boolean;
end;
TWarframeNotifyEvent=record
NotifyTimeLeft: LongWord;
ID: Integer;
FlashOnTaskbar: Boolean;
PlaySound: Boolean;
Volume: Integer;
TrayPopupBalloon: Boolean;
end;
TWarframeEventList=record
WarframeEvent: Array of TWarframeEvent;
WarframeEventCount: Integer;
NotifyEvent: TWarframeNotifyEvent;
end;
TUpdateFromTwitterThread=class(TThread)
TwitterURL: String;
Procedure Execute; override;
end;
TUpdateFromRSSThread=class(TThread)
RSS_URL: String;
Procedure Execute; override;
end;
var部分(模块)
执行科:
procedure TForm1.TimerUpdateEventsTimer(Sender: TObject);
begin
UpdateFromTwitterThread:=TUpdateFromTwitterThread.Create(True);
UpdateFromTwitterThread.TwitterURL:=form2.EditAlertsURL.Text;
UpdateFromTwitterThread.Start;
UpdateFromRSSThread:=TUpdateFromRSSThread.Create(True);
UpdateFromRSSThread.RSS_URL:=form2.EditInvansionsURL.Text;
UpdateFromRSSThread.Start;
end;
procedure TUpdateFromTwitterThread.Execute;
var
HTTPClient: TIdHTTP;
IOHandler: TIdSSLIOHandlerSocketOpenSSL;
S, S2: String;
i, l: Integer;
NewAlertDate: TDateTime;
ErrorLogFile: TextFile;
begin
HTTPClient:=TIdHTTP.Create(nil);
IOHandler:=TIdSSLIOHandlerSocketOpenSSL.Create(nil);
try
try
HTTPClient.IOHandler:=IOHandler;
HTTPClient.HandleRedirects:=True;
S:=HTTPClient.Get(self.TwitterURL);
except
Assign(ErrorLogFile, AppPath+'Error.log');
if not(FileExists(AppPath+'Error.log')) then
Rewrite(ErrorLogFile);
Append(ErrorLogFile);
Writeln(ErrorLogFile, DateTimeToStr(Now)+' '+LS_ErrorConnection+' '+self.TwitterURL+'; Error code: '+IntToStr(HTTPClient.ResponseCode));
Close(ErrorLogFile);
self.Terminate;
HTTPClient.Free;
IOHandler.Free;
end;
finally
HTTPClient.Free;
IOHandler.Free;
end;
if Application.Terminated or self.Terminated then exit;
S:=copy(S, pos('<b>WarframeAlerts</b></span>', S), Length(S)-pos('<b>WarframeAlerts</b></span>', S));
while pos('tweet-timestamp js-permalink js-nav', S)>0 do begin
S:=copy(S, pos('tweet-timestamp js-permalink js-nav', S)+35, Length(S)-pos('tweet-timestamp js-permalink js-nav', S)-35);
S2:=copy(S, pos('data-time="', S)+11, Length(S)-pos('data-time="', S)-11);
NewAlertDate:=StrToInt(copy(S2, 1, pos('"', S2)-1));
S2:=copy(S, pos('<p class="js-tweet-text tweet-text">', S)+36, pos('</p>', S)-pos('<p class="js-tweet-text tweet-text">', S)-36);
for i:= 0 to WarframeEventList.WarframeEventCount-1 do
if (WarframeEventList.WarframeEvent[i].EventDate=NewAlertDate) and (WarframeEventList.WarframeEvent[i].Planet=copy(S2, 1, pos(')', S2))) then
NewAlertDate:=0;
if NewAlertDate=0 then continue;
Inc(WarframeEventList.WarframeEventCount);
SetLength(WarframeEventList.WarframeEvent, WarframeEventList.WarframeEventCount);
for i:= 0 to WarframeEventList.WarframeEventCount-2 do begin
if WarframeEventList.WarframeEvent[i].EventDate>NewAlertDate then begin
for l:=WarframeEventList.WarframeEventCount-1 downto i+1 do
WarframeEventList.WarframeEvent[l]:=WarframeEventList.WarframeEvent[l-1];
Break;
end;
end;
if i<=WarframeEventList.NotifyEvent.ID then Inc(WarframeEventList.NotifyEvent.ID);
WarframeEventList.WarframeEvent[i].GUID:='';
WarframeEventList.WarframeEvent[i].ItemIndex:=-2;
WarframeEventList.WarframeEvent[i].EventType:=1;
WarframeEventList.WarframeEvent[i].Planet:=copy(S2, 1, pos(')', S2));
S2:=copy(S2, Length(WarframeEventList.WarframeEvent[i].Planet)+3, Length(S2)-Length(WarframeEventList.WarframeEvent[i].Planet));
WarframeEventList.WarframeEvent[i].Mission:=copy(S2, 1, pos(' -', S2)-1);
WarframeEventList.WarframeEvent[i].EventDate:=NewAlertDate;
S2:=copy(S2, Length(WarframeEventList.WarframeEvent[i].Mission)+4, Length(S2)-Length(WarframeEventList.WarframeEvent[i].Mission));
WarframeEventList.WarframeEvent[i].Time:=StrToInt(copy(S2, 1, pos('m', S2)-1))-1;
S2:=copy(S2, pos('-', S2)+2, Length(S2)-pos('-', S2));
WarframeEventList.WarframeEvent[i].RewardCredits:=StrToInt(copy(S2, 1, pos('cr', S2)-1));
WarframeEventList.WarframeEvent[i].RewardOther:=copy(S2, pos('cr', S2)+5, Length(S2)-pos('cr', S2));
WarframeEventList.WarframeEvent[i].RewardOtherAmount:=1;
WarframeEventList.WarframeEvent[i].Notified:=False;
WarframeEventList.WarframeEvent[i].Hidden:=False;
end;
self.Free;
end;
procedure TUpdateFromRSSThread.Execute;
var
HTTPClient: TIdHTTP;
IOHandler: TIdSSLIOHandlerSocketOpenSSL;
S, S2, S3: String;
i: Integer;
NewEventType: Byte;
ErrorLogFile: TextFile;
begin
HTTPClient:=TIdHTTP.Create(nil);
IOHandler:=TIdSSLIOHandlerSocketOpenSSL.Create(nil);
try
try
HTTPClient.IOHandler:=IOHandler;
HTTPClient.HandleRedirects:=True;
S:=HTTPClient.Get(self.RSS_URL);
except
Assign(ErrorLogFile, AppPath+'Error.log');
if not(FileExists(AppPath+'Error.log')) then
Rewrite(ErrorLogFile);
Append(ErrorLogFile);
Writeln(ErrorLogFile, DateTimeToStr(Now)+' '+LS_ErrorConnection+' '+self.RSS_URL+'; Error code: '+IntToStr(HTTPClient.ResponseCode));
Close(ErrorLogFile);
self.Terminate;
HTTPClient.Free;
IOHandler.Free;
end;
finally
HTTPClient.Free;
IOHandler.Free;
end;
if Application.Terminated or self.Terminated then exit;
for i:= 0 to WarframeEventList.WarframeEventCount-1 do
if (WarframeEventList.WarframeEvent[i].EventType=2) or (WarframeEventList.WarframeEvent[i].EventType=3) then
WarframeEventList.WarframeEvent[i].Time:=0;
while pos('<item>', S)>0 do begin
S:=copy(S, pos('<item>', S)+6, Length(S)-pos('<item>', S)-6);
S2:=LowerCase(copy(S, pos('<author>', S)+8, pos('</author>', S)-pos('<author>', S)-8));
NewEventType:=0;
if S2='alert' then
NewEventType:=1;
if S2='invasion' then
NewEventType:=2;
if S2='outbreak' then
NewEventType:=3;
if NewEventType=1 then
Continue;
S2:=LowerCase(copy(S, pos('<guid>', S)+6, pos('</guid>', S)-pos('<guid>', S)-6));
for i:= 0 to WarframeEventList.WarframeEventCount-1 do
if ((WarframeEventList.WarframeEvent[i].EventType=2) or (WarframeEventList.WarframeEvent[i].EventType=3)) and (WarframeEventList.WarframeEvent[i].GUID=S2) then begin
WarframeEventList.WarframeEvent[i].Time:=1;
NewEventType:=255;
end;
if NewEventType=255 then
Continue;
Inc(WarframeEventList.WarframeEventCount);
SetLength(WarframeEventList.WarframeEvent, WarframeEventList.WarframeEventCount);
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].ItemIndex:=-2;
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].GUID:=S2;
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].EventType:=NewEventType;
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].Time:=1;
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].RewardOther:='';
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].RewardOtherAmount:=0;
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].RewardCredits:=0;
S2:=copy(S, pos('<title>', S)+7, pos('</title>', S)-pos('<title>', S)-7);
if NewEventType=2 then begin
S2:=Copy(S2, 1, pos(' - ', S2)-1);
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].RewardOther:=S2;
S3:=Copy(S2, 1, pos('VS.', S2)-1);
S3:=Copy(S3, pos('(', S3), Length(S3)-pos('(', S3)+1);
if pos('x ', S3)>0 then
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].RewardOtherAmount:=StrToInt(copy(S3, 2, pos('x ', S3)-2));
if pos('K)', S3)>0 then
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].RewardCredits:=StrToInt(copy(S3, 2, pos('K)', S3)-2))*1000;
S3:=Copy(S2, pos('VS.', S2)+4, Length(S2)-pos('VS.', S2)-3);
S3:=Copy(S3, pos('(', S3), Length(S3)-pos('(', S3)+1);
if pos('x ', S3)>0 then
if WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].RewardOtherAmount<StrToInt(copy(S3, 2, pos('x ', S3)-2)) then
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].RewardOtherAmount:=StrToInt(copy(S3, 2, pos('x ', S3)-2));
if pos('K)', S3)>0 then
if WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].RewardCredits<StrToInt(copy(S3, 2, pos('K)', S3)-2))*1000 then
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].RewardCredits:=StrToInt(copy(S3, 2, pos('K)', S3)-2))*1000;
end;
if NewEventType=3 then begin
S2:=Copy(S2, 1, pos(' - ', S2)-1);
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].RewardOther:='';
if pos('x ', S2)>0 then begin
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].RewardOtherAmount:=StrToInt(copy(S2, 1, pos('x ', S2)-1));
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].RewardOther:=S2;
end;
if copy(S2, Length(S2), 1)='K' then
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].RewardCredits:=StrToInt(copy(S2, 1, Length(S2)-1))*1000;
S2:=copy(S2, 1, Length(S2)-1);
end;
S2:=copy(S, pos('<title>', S)+7, pos('</title>', S)-pos('<title>', S)-7);
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].Planet:=Copy(S2, pos(' - ', S2)+3, Length(S2)-pos(' - ', S2));
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].Mission:=copy(S, pos('<author>', S)+8, pos('</author>', S)-pos('<author>', S)-8);
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].Notified:=False;
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].Hidden:=False;
end;
self.Free;
end;
外部(全局)对象,以避免每分钟销毁/重新创建它们
4) 当我试图关闭应用程序时,如果线程处于活动状态,它就会死锁。即使线程没有完成其工作或可能分离它们,是否有终止线程的方法
Execute
中运行循环(而不是只执行一次操作然后终止),并在未终止时检查,或等待循环中的事件以允许完全关闭
Terminate
或一个信号来指示它们应该结束工作。如果FreeOnTerminate
为True,则主线程中不需要额外的终止和清理代码您在这里提出了很多问题,然后添加了大量代码。代码被严重破坏。我可以看到:
- 从
内部错误调用Execute
。这完全是错误的。如果需要自毁线程,必须使用Self.Free
FreeOnTerminate
- 在出现异常的情况下,您可以双重释放
和HTTPClient
IOHandler
- 在这两个线程中发生变异的列表中似乎存在危险的数据竞争
Start
,该怎么办
在我看来,这似乎表明了你的根本误解。线程的代码只不过是一个函数调用。在TThread
的情况下,该函数是Execute
。当线程启动时,调用Execute
。当Execute
返回时,该线程的有效期结束。一旦Execute
返回,它就不能重新启动
这意味着,如果希望单个线程对单个任务执行多次重复,则需要在Execute
方法中实现一个循环
您还声明:
我不会问如何创建循环线程,因为它们在这里不适用
对不起,那是不对的。使线程多次执行任务的方法是通过循环
更一般地说,我觉得如果你能利用一个更高层次的并行库,你会得到更好的服务。最好的是OTL 如果您不希望采纳该建议,那么我将如何着手构建您的计划:
,但在Execute
方法中没有终止循环
Terminate
,设置取消事件,并在两个线程上调用Free
。然后应用程序可以安全终止Execute
下的本地线程。或者更好的是,助手方法中的局部变量执行
调用。您的Execute
方法非常大
除此之外,名单上还有数据竞争。关于如何解决这个问题,我不能给你详细的建议。显然需要进行一些序列化。我认为这里的问题太多了。我想我可以回答其中的一些问题,但我无法面对回答所有问题。不要周期性地创建和销毁它们。在未终止时,在
Execute
方法中执行类似的循环,并在一段时间内等待退出事件(您希望使用它检查那些在线频道)。如果等待函数返回超时结果,则可以检查这些通道。如果它返回事件的信号状态,则可以退出结束线程上下文的Execute
方法。例如,在伪代码中,如果“释放”线程,则不能“重用”它。谢谢!我想我确实会重新处理这个问题,并尝试实现循环线程。-哇。好像我以前从未见过这个答案。我完全知道如何创建循环线程,我在其他应用程序中将其用于套接字。现在看看代码,告诉我如何在循环中以我上面发布的优雅方式运行它-感谢您提供有关FreeOnTerminate的信息。如果我理解正确,它将在执行完成后调用self.free-是的,我知道
procedure TForm1.TimerUpdateEventsTimer(Sender: TObject);
begin
UpdateFromTwitterThread:=TUpdateFromTwitterThread.Create(True);
UpdateFromTwitterThread.TwitterURL:=form2.EditAlertsURL.Text;
UpdateFromTwitterThread.Start;
UpdateFromRSSThread:=TUpdateFromRSSThread.Create(True);
UpdateFromRSSThread.RSS_URL:=form2.EditInvansionsURL.Text;
UpdateFromRSSThread.Start;
end;
procedure TUpdateFromTwitterThread.Execute;
var
HTTPClient: TIdHTTP;
IOHandler: TIdSSLIOHandlerSocketOpenSSL;
S, S2: String;
i, l: Integer;
NewAlertDate: TDateTime;
ErrorLogFile: TextFile;
begin
HTTPClient:=TIdHTTP.Create(nil);
IOHandler:=TIdSSLIOHandlerSocketOpenSSL.Create(nil);
try
try
HTTPClient.IOHandler:=IOHandler;
HTTPClient.HandleRedirects:=True;
S:=HTTPClient.Get(self.TwitterURL);
except
Assign(ErrorLogFile, AppPath+'Error.log');
if not(FileExists(AppPath+'Error.log')) then
Rewrite(ErrorLogFile);
Append(ErrorLogFile);
Writeln(ErrorLogFile, DateTimeToStr(Now)+' '+LS_ErrorConnection+' '+self.TwitterURL+'; Error code: '+IntToStr(HTTPClient.ResponseCode));
Close(ErrorLogFile);
self.Terminate;
HTTPClient.Free;
IOHandler.Free;
end;
finally
HTTPClient.Free;
IOHandler.Free;
end;
if Application.Terminated or self.Terminated then exit;
S:=copy(S, pos('<b>WarframeAlerts</b></span>', S), Length(S)-pos('<b>WarframeAlerts</b></span>', S));
while pos('tweet-timestamp js-permalink js-nav', S)>0 do begin
S:=copy(S, pos('tweet-timestamp js-permalink js-nav', S)+35, Length(S)-pos('tweet-timestamp js-permalink js-nav', S)-35);
S2:=copy(S, pos('data-time="', S)+11, Length(S)-pos('data-time="', S)-11);
NewAlertDate:=StrToInt(copy(S2, 1, pos('"', S2)-1));
S2:=copy(S, pos('<p class="js-tweet-text tweet-text">', S)+36, pos('</p>', S)-pos('<p class="js-tweet-text tweet-text">', S)-36);
for i:= 0 to WarframeEventList.WarframeEventCount-1 do
if (WarframeEventList.WarframeEvent[i].EventDate=NewAlertDate) and (WarframeEventList.WarframeEvent[i].Planet=copy(S2, 1, pos(')', S2))) then
NewAlertDate:=0;
if NewAlertDate=0 then continue;
Inc(WarframeEventList.WarframeEventCount);
SetLength(WarframeEventList.WarframeEvent, WarframeEventList.WarframeEventCount);
for i:= 0 to WarframeEventList.WarframeEventCount-2 do begin
if WarframeEventList.WarframeEvent[i].EventDate>NewAlertDate then begin
for l:=WarframeEventList.WarframeEventCount-1 downto i+1 do
WarframeEventList.WarframeEvent[l]:=WarframeEventList.WarframeEvent[l-1];
Break;
end;
end;
if i<=WarframeEventList.NotifyEvent.ID then Inc(WarframeEventList.NotifyEvent.ID);
WarframeEventList.WarframeEvent[i].GUID:='';
WarframeEventList.WarframeEvent[i].ItemIndex:=-2;
WarframeEventList.WarframeEvent[i].EventType:=1;
WarframeEventList.WarframeEvent[i].Planet:=copy(S2, 1, pos(')', S2));
S2:=copy(S2, Length(WarframeEventList.WarframeEvent[i].Planet)+3, Length(S2)-Length(WarframeEventList.WarframeEvent[i].Planet));
WarframeEventList.WarframeEvent[i].Mission:=copy(S2, 1, pos(' -', S2)-1);
WarframeEventList.WarframeEvent[i].EventDate:=NewAlertDate;
S2:=copy(S2, Length(WarframeEventList.WarframeEvent[i].Mission)+4, Length(S2)-Length(WarframeEventList.WarframeEvent[i].Mission));
WarframeEventList.WarframeEvent[i].Time:=StrToInt(copy(S2, 1, pos('m', S2)-1))-1;
S2:=copy(S2, pos('-', S2)+2, Length(S2)-pos('-', S2));
WarframeEventList.WarframeEvent[i].RewardCredits:=StrToInt(copy(S2, 1, pos('cr', S2)-1));
WarframeEventList.WarframeEvent[i].RewardOther:=copy(S2, pos('cr', S2)+5, Length(S2)-pos('cr', S2));
WarframeEventList.WarframeEvent[i].RewardOtherAmount:=1;
WarframeEventList.WarframeEvent[i].Notified:=False;
WarframeEventList.WarframeEvent[i].Hidden:=False;
end;
self.Free;
end;
procedure TUpdateFromRSSThread.Execute;
var
HTTPClient: TIdHTTP;
IOHandler: TIdSSLIOHandlerSocketOpenSSL;
S, S2, S3: String;
i: Integer;
NewEventType: Byte;
ErrorLogFile: TextFile;
begin
HTTPClient:=TIdHTTP.Create(nil);
IOHandler:=TIdSSLIOHandlerSocketOpenSSL.Create(nil);
try
try
HTTPClient.IOHandler:=IOHandler;
HTTPClient.HandleRedirects:=True;
S:=HTTPClient.Get(self.RSS_URL);
except
Assign(ErrorLogFile, AppPath+'Error.log');
if not(FileExists(AppPath+'Error.log')) then
Rewrite(ErrorLogFile);
Append(ErrorLogFile);
Writeln(ErrorLogFile, DateTimeToStr(Now)+' '+LS_ErrorConnection+' '+self.RSS_URL+'; Error code: '+IntToStr(HTTPClient.ResponseCode));
Close(ErrorLogFile);
self.Terminate;
HTTPClient.Free;
IOHandler.Free;
end;
finally
HTTPClient.Free;
IOHandler.Free;
end;
if Application.Terminated or self.Terminated then exit;
for i:= 0 to WarframeEventList.WarframeEventCount-1 do
if (WarframeEventList.WarframeEvent[i].EventType=2) or (WarframeEventList.WarframeEvent[i].EventType=3) then
WarframeEventList.WarframeEvent[i].Time:=0;
while pos('<item>', S)>0 do begin
S:=copy(S, pos('<item>', S)+6, Length(S)-pos('<item>', S)-6);
S2:=LowerCase(copy(S, pos('<author>', S)+8, pos('</author>', S)-pos('<author>', S)-8));
NewEventType:=0;
if S2='alert' then
NewEventType:=1;
if S2='invasion' then
NewEventType:=2;
if S2='outbreak' then
NewEventType:=3;
if NewEventType=1 then
Continue;
S2:=LowerCase(copy(S, pos('<guid>', S)+6, pos('</guid>', S)-pos('<guid>', S)-6));
for i:= 0 to WarframeEventList.WarframeEventCount-1 do
if ((WarframeEventList.WarframeEvent[i].EventType=2) or (WarframeEventList.WarframeEvent[i].EventType=3)) and (WarframeEventList.WarframeEvent[i].GUID=S2) then begin
WarframeEventList.WarframeEvent[i].Time:=1;
NewEventType:=255;
end;
if NewEventType=255 then
Continue;
Inc(WarframeEventList.WarframeEventCount);
SetLength(WarframeEventList.WarframeEvent, WarframeEventList.WarframeEventCount);
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].ItemIndex:=-2;
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].GUID:=S2;
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].EventType:=NewEventType;
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].Time:=1;
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].RewardOther:='';
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].RewardOtherAmount:=0;
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].RewardCredits:=0;
S2:=copy(S, pos('<title>', S)+7, pos('</title>', S)-pos('<title>', S)-7);
if NewEventType=2 then begin
S2:=Copy(S2, 1, pos(' - ', S2)-1);
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].RewardOther:=S2;
S3:=Copy(S2, 1, pos('VS.', S2)-1);
S3:=Copy(S3, pos('(', S3), Length(S3)-pos('(', S3)+1);
if pos('x ', S3)>0 then
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].RewardOtherAmount:=StrToInt(copy(S3, 2, pos('x ', S3)-2));
if pos('K)', S3)>0 then
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].RewardCredits:=StrToInt(copy(S3, 2, pos('K)', S3)-2))*1000;
S3:=Copy(S2, pos('VS.', S2)+4, Length(S2)-pos('VS.', S2)-3);
S3:=Copy(S3, pos('(', S3), Length(S3)-pos('(', S3)+1);
if pos('x ', S3)>0 then
if WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].RewardOtherAmount<StrToInt(copy(S3, 2, pos('x ', S3)-2)) then
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].RewardOtherAmount:=StrToInt(copy(S3, 2, pos('x ', S3)-2));
if pos('K)', S3)>0 then
if WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].RewardCredits<StrToInt(copy(S3, 2, pos('K)', S3)-2))*1000 then
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].RewardCredits:=StrToInt(copy(S3, 2, pos('K)', S3)-2))*1000;
end;
if NewEventType=3 then begin
S2:=Copy(S2, 1, pos(' - ', S2)-1);
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].RewardOther:='';
if pos('x ', S2)>0 then begin
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].RewardOtherAmount:=StrToInt(copy(S2, 1, pos('x ', S2)-1));
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].RewardOther:=S2;
end;
if copy(S2, Length(S2), 1)='K' then
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].RewardCredits:=StrToInt(copy(S2, 1, Length(S2)-1))*1000;
S2:=copy(S2, 1, Length(S2)-1);
end;
S2:=copy(S, pos('<title>', S)+7, pos('</title>', S)-pos('<title>', S)-7);
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].Planet:=Copy(S2, pos(' - ', S2)+3, Length(S2)-pos(' - ', S2));
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].Mission:=copy(S, pos('<author>', S)+8, pos('</author>', S)-pos('<author>', S)-8);
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].Notified:=False;
WarframeEventList.WarframeEvent[WarframeEventList.WarframeEventCount-1].Hidden:=False;
end;
self.Free;
end;
HTTPClient: TIdHTTP;
IOHandler: TIdSSLIOHandlerSocketOpenSSL;