Я никогда не задавал вопросов ни в одном сообществе, так как всегда решал проблемы сам или мог найти их в Интернете. Но с этим я зашел в тупик и нуждаюсь в помощи! Чтобы было предельно ясно — я преобразовал простое приложение, найденное в другом месте, чтобы оно использовало объект Tthread. Идея проста — приложение проверяет онлайн через веб-сервис, через компонент THTTPRIO, погоду и заносит результаты в строки Memo1.
Нажав на Button1, мы делаем это стандартно — с помощью THTTPRIO, наложенного на Form1 (он здесь называется 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;
В процедуре Execute в блоке WeatherThread1 я помещаю этот код:
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. Но это работает какое-то время, когда я нажимаю ПЕРВУЮ кнопку 1 и ПОСЛЕ ЭТОГО кнопку 2 (но работает какое-то время, всего 5-7 кликов). Я предполагаю, что делаю что-то не так, но не могу понять, где проблема и как ее решить. Похоже, что код в threaded unit не потокобезопасен, но должен быть. Помогите, пожалуйста, как заставить HTTPRIO работать в потоке!!!
Полный код в архиве можно найти здесь.
CoInitialize
. Delphi обрабатывает вызов при инициализации 'ComObj.pas' для основного потока, но для отдельного потока вы бы назвали его самостоятельно. Кстати, вы за прокси? - person Sertac Akyuz   schedule 09.08.2010