线程对象的成员变量为VCL类,访问该成员变量的方法和属性,用不用使用Synchronize()?(200分)

  • 主题发起人 主题发起人 GOHKI
  • 开始时间 开始时间
G

GOHKI

Unregistered / Unconfirmed
GUEST, unregistred user!
如果说线程对象的成员变量都是在该对象的线程内执行,
那么是否不用考虑线程安全问题?
为什么我使用TClientSocket时直接调用Open不行?
必须加上Synchronize才可以。
如果这样也要考虑线程安全的问题,那么大概哪些VCL类的哪些方法和属性是线程安全的?
另外,我想在线程对象里发送字符串到主线程里,用什么方法比较好?
先谢谢各位大侠了!
 
看看DELPHI自己的帮助先:
Data access components are thread-safe as follows: For BDE-enabled datasets,
each thread must have its own database session component. The one exception to
this is when you are using Access drivers, which are built using a Microsoft
library that is not thread-safe. For dbDirect, as long as the vendor client
library is thread-safe, the dbDirect components will be thread-safe. ADO and
InterbaseExpress components are thread-safe.
When using data access components, you must still wrap all calls that involve
data-aware controls in the Synchronize method. Thus, for example, you need to
synchronize calls that link a data control to a dataset by setting the DataSet
property of the data source object, but youdo
n抰 need to synchronize to
access the data in a field of the dataset.
For more information about using database sessions with threads in BDE-enabled
applications, see Managing multiple sessions.
VisualCLX objects are not thread-safe.
DataCLX objects are thread-safe.
Graphics objects are thread-safe. Youdo
not need to use the main
VCL or CLX thread to access TFont, TPen, TBrush, TBitmap
, TMetafile (VCL only), TDrawing (CLX only), or TIcon. Canvas objects can be
used outside the Synchronize method by locking them.
While list objects are not thread-safe, you can use a thread-safe version,
TThreadList, instead of TList.
线程安全的类是不用Synchronize的,只有非线程安全的类才需要,至于哪些是线程安全而
哪些不是,你看看上面的帮助就行了。
 
帮助里有讲:)
Synchronize在县城里经常要用道的。。。。
 
to xianjun:
那段话是不是说也要建立线程对象自己的TSession对象?
我使用TDatabase和TQuery作为线程对象的成员好像没什么问题,
但是TClientSocket却有问题,调用Open之后根本不连接。
 
1 可以使用消息
2 可以使用TEvent
3 TThread的功能很弱。如果逻辑复杂,最好一上来就使用互斥元,
调试起来方便(那样和单线程差不多了)。
 
to czonghui:
逻辑并不复杂,访问主线程紧紧是为了显示程序的运行信息。
现在主要是TClientSocket的问题。
 
TClientSocket请使用阻塞方式,非阻塞方式可能会有问题(当然可以解决),而且
也没必要非阻塞方式,同时使用多线层和窗口消息是一种不明智地方法。
线层和主线层传递字符串既可以直接共享内存的传递,例如用全局变量,用类成员变量,
都可以(要线层安全,可以使用互斥对象),如果需要同步解决的传递,可以用SendMessage到
主线层的窗口上。当然,我们可以把原来主线层处理这个消息的窗口handle预先传递给
线层,例如TMythread.create(....,form1.handle)。
 
使用TClientSocket,不论是阻塞还是非阻塞,
都应该没有问题(我现在做的项目就是使用TClientSocket的非阻塞方式),
只是如果使用非阻塞方式,在你的线程里还应处理消息(PeekMessage和DispatchMessage)。
 
to wenyue:
能给出阻塞方式的例子吗?
to 坏蟑螂:
能给出使用PeekMessage和DispatchMessage的例子吗?
谢谢大家了!
 
关于PEEKMESSAGE,DISPATHMESSAGE的例子可以看VCL的类库FORMS单元内的TAPPLICATION
的PROCESSMESSAGES,这就是单个线层让别的处理过程处理消息的例子。
坏蟑螂:我认为你的用法真的是一种坏用法哦,多线层的程序不如使用阻塞方式的SOCKET。
阻塞方式的,只需要CLIENTSOCKET.clientType:=ctBlocking就可以了。
然后你就不再使用On....来处理读写连接等,例如写成如下:
ClientSocket.ClientType:=ctBlocking;
Try
Try
ClientSocket.Open;
ClientSocket.SendBuf.......
repeat
ClientSocket.RecvBuf(..
...................
ClientSocket.SendBuf(....
do
Something
until .......
except
end;
finally
ClientSocket.Close;
end;
 
to wenyue: 我并无意评判谁的方法好坏优劣,
只是想告诉他两种方法都可以,也不否认阻塞
方式更为简单一些。
实际上我以前的绝大多数方式都是阻塞式,只
是这次因为特殊原因才使用了非阻塞方式。不
同的方法适用于不同的问题,世上没有包医百
病的万能药,你说是吗?
所以,我出此言纯属技术讨论,丝毫没有诋毁
你的“高深方法”的意思。你认为我们俩在这
里争个谁好谁坏很有趣吗?你认为我们在这里
分个高下,其它人就会认为“阻塞/非阻塞”
一定比“非阻塞/阻塞”差吗?如果你喜欢争
论谁高谁低,而不是进行技术讨论,那只好对
不起,恕我不奉陪了。
 
2 坏蟑螂:
我仍然那样认为。尽管你可能觉得逆耳。个人看法而已,坏就是坏,一定好不了。
争论,有时候仅仅是提醒而已,如果你这么认为,你以后说的我不会说任何不字。
哪怕是“不好”甚至“不坏”。
也许性格使然,个人认为技术上的东西就是如此,从来不认为自己很行,更不认为自己
不行。没有任何一个人精通所有的,学习是唯一之道,而讨论是学习的一个重要途径。
DELPHIBBS最大的缺陷是什么?缺乏有一定基础的技术人员,哪怕只是有真正基础的
程序员的讨论。
争论也许在你是有目的的。但有句话:“你不是我,你又怎么知道我是这样想的呢”?
不要用你自己的心态去揣摩别人的思想。而要学会从别人的行为去揣摩自己。
 
如果要在线程里有要访问主线程里的控件的方法就要
用到sycronize,各位大虾不知道我说的对不对
 
问题解决了,我还是使用了阻塞方式,这样就可以连接,
非阻塞方式好像必须用Synchronize才行,否则调用Open后没有任何反映,
好像根本就没有连接。
谢谢各位!
 
后退
顶部