我怎么能得到行动,我的线程在恢复后暂停时做了(抱歉我的英文不好) 好的,我会用代码解释
function mythreadf(p:Pointer):DWORD stdcall;
var i:Integer;
begin
for i:=0 to 1000000 do begin
if myevent.WaitFor(INFINITE)=wrsignaled
then
begin
if Form1.RadioButton1.Checked then ShowMessage('Checked');
Form1.Label1.Caption:=IntToStr(i);
end;
end;
end;
我正在使用resetevent和setevent暂停和恢复我的线程 通过单击resetevent按钮暂停我的线程然后我检查radiobotton1之后再次使用setevent恢复我的线程.dont发送错误发生和应用程序关闭:(
任何人都可以帮助我解决这个问题
问候 编辑1: 错误图片 http://i49.tinypic.com/11r7nkn.jpg
答案 0 :(得分:5)
直接在工作线程中访问VCL UI控件不是线程安全的(即使ShowMessage()不是线程安全的。直接使用Win32 API MessageBox())。各种不好的事情都可能发生,包括崩溃。您必须将UI访问权委托给主线程。为此,TThread类有一个Synchronize()方法。或者您可以使用您选择的任何其他线程间同步,例如使用SendMessage()通过AllocateHWnd()或CreateWindow / Ex()将自定义消息发送到在主线程中创建的隐藏窗口。
答案 1 :(得分:0)
正如雷米所说,你的线程不应该访问该复选框。这也是糟糕的编程风格。你的后台线程有目的吗?那个目的会帮助你找到一个名字。如果您创建一个继承自TThread的类,您将获得更远,更快。
interface
type
TMyElephantCountingThread = class(TThread)
protected
FResultStr:String; // holds something for later display on the user interface
FOptionChecked:Boolean; // set from main thread, to tell background thread whether or not a checkbox option is checked.
....
end;
....
implementation
....
function TMyElephantCountingThread.ElephantCounterResults;
begin
// all data fields in here is local to this thread
if FOptionChecked then
FResultStr := IntToStr(FIntegerValue);
end;
正如您所看到的,我上面的代码只使用属于我的线程对象的字段。
如果需要将FOptionChecked设置为等于Checkbox.checked的值,则必须在主线程中完成。
您无法将前台线程(可以访问VCL对象)的写入代码复制并粘贴到后台线程代码中(无法安全地访问这些对象),也不会出现问题。