私はいつも自分で問題を解決したか、オンラインで見つけることができたので、コミュニティで質問したことはありません. しかし、これで私は行き止まりになり、助けが必要です! わかりやすくするために、他の場所で見つけた単純なアプリを Tthread オブジェクトを使用するように変換しました。アイデアは単純です。アプリは Web サービスを使用してオンラインでチェックし、THTTPRIO コンポーネントを介して天気を調べ、結果を Memo1 行に入れます。
Button1 をクリックすると、標準的な方法で実行されます。Form1 に配置された THTTPRIO を使用し (元のアプリと同様に、ここでは htt と呼ばれます)、メインおよび唯一のスレッドを使用します。
procedure TForm1.Button1Click(Sender: TObject);
var
wf:WeatherForecasts;
res:ArrayOfWeatherData;
i:integer;
begin
wf:=(htt as WeatherForecastSoap).GetWeatherByPlaceName(edit1.Text);
if wf.PlaceName<> '' then
res:=wf.Details;
memo1.Lines.Add('The min and max temps in Fahrenheit is:');
memo1.Lines.Add(' ');
for i:= 0 to high(res) do
begin
memo1.Lines.Add(res[i].Day+' - '+ ' Max Temp. Fahr: '+res[i].MaxTemperatureF+' - '+'Min Temp Fahr: '+res[i].MinTemperatureF);
end
end;
Button2 をクリック – クラス TThread を使用します
procedure TForm1.Button2Click(Sender: TObject);
var WFThread:WeatherThread;
begin
WFThread := WeatherThread.Create (True);
WFThread.FreeOnTerminate := True;
WFThread.Place := Edit1.Text;
WFThread.Resume;
end;
WeatherThread1 ユニットの Execute プロシージャに、次のコードを追加しました。
procedure WeatherThread.Execute;
begin
{ Place thread code here }
GetForecast;
Synchronize (ShowWeather);
end;
...そして GetForecast コード:
procedure WeatherThread.GetForecast;
var
HTTPRIO: THTTPRIO;
wf:WeatherForecasts;
res:ArrayOfWeatherData;
i:integer;
begin
HTTPRIO := THTTPRIO.Create(nil);
HTTPRIO.URL := 'http://www.webservicex.net/WeatherForecast.asmx';
HTTPRIO.WSDLLocation := 'http://www.webservicex.net/WeatherForecast.asmx?WSDL';
HTTPRIO.Service := 'WeatherForecast';
HTTPRIO.Port := 'WeatherForecastSoap';
wf:=(HTTPRIO as WeatherForecastSoap).GetWeatherByPlaceName(Place);
if Lines=nil then Lines:=TStringList.Create;
if wf.PlaceName<> '' then
res:=wf.Details;
Lines.Clear;
for i:= 0 to high(res) do
begin
Lines.Add(res[i].Day+' - '+ ' Max Temp. Fahr: '+res[i].MaxTemperatureF+' - '+'Min Temp Fahr: '+res[i].MinTemperatureF);
end;
end;
プロシージャ ShowWeather は Form1.Memo1 に結果を表示します。ここで問題があります。メイン スレッドで Button1 をクリックすると、すべて正常に動作します。しかしもちろん、HTTPRIO コンポーネントが通信すると、フォームがフリーズします。
Button2 を使用して、コードを別のスレッドに入れましたが、動作したくありません! 何か奇妙なことが起こります。アプリケーションを起動して Button2 をクリックすると、HTTPRIO コンポーネントの使用時にエラーが発生します。しかし、最初の Button1 と AFTER THAT Button2 をクリックすると、しばらくは機能します (ただし、しばらくは機能しますが、5 ~ 7 回のクリックのみです)。何か間違ったことをしていると思いますが、問題の場所と解決方法がわかりません。スレッド化されたユニットのコードはスレッドセーフではないように見えますが、スレッドセーフである必要があります。スレッドで HTTPRIO を動作させる方法を教えてください!!!
圧縮された完全なコードはこちらにあります。