안전 System.Windows.Forms.Control
하지 않은 다른 속성과 비교하여 다른 스레드에서 의 속성 일부를 업데이트하는 것이 안전한 이유는 무엇 이며 프로그래머는 Delegate
?
예를 들어, ForeColor
비교 Text
.
누군가 디자인 관점에서 이것을 설명 할 수 있습니까?
일부 속성 액세스가 불법 크로스 스레드 오류를 발생시키는 이유와 그렇지 않은 이유에 대한 귀하의 질문에 답하려면의 소스 코드를System.Windows.Forms.Control
참조하십시오 . 약간의 파고가 필요하지만 Text
속성 을 얻는 것과 같이 스레드로부터 안전한 것으로 일부 액세스가 제안 되었지만 설정 하지 않은 것처럼 보입니다 .
실제로 모든 제어 액세스를 스레드로부터 안전하지 않은 것으로 간주하는 것이 가장 좋은 방법입니다.
public virtual string Text {
get {
if (CacheTextInternal) {
return(text == null) ? "" : text;
}
else {
return WindowText;
}
}
set {
if (value == null) {
value = "";
}
if (value == Text) {
return;
}
if (CacheTextInternal) {
text = value;
}
WindowText = value;
OnTextChanged(EventArgs.Empty);
if( this.IsMnemonicsListenerAxSourced ){
for( Control ctl = this; ctl != null; ctl = ctl.ParentInternal ) {
ActiveXImpl activeXImpl = (ActiveXImpl)ctl.Properties.GetObject(PropActiveXImpl);
if( activeXImpl != null ) {
activeXImpl.UpdateAccelTable();
break;
}
}
}
}
}
위 코드에서 내부 WindowText 속성의 사용에 유의하십시오.
/// <devdoc>
/// The current text of the Window; if the window has not yet been created, stores it in the control.
/// If the window has been created, stores the text in the underlying win32 control.
/// This property should be used whenever you want to get at the win32 control's text. For all other cases,
/// use the Text property - but note that this is overridable, and any of your code that uses it will use
/// the overridden version in controls that subclass your own.
/// </devdoc>
internal virtual string WindowText {
get {
if (!IsHandleCreated) {
if (text == null) {
return "";
}
else {
return text;
}
}
using (new MultithreadSafeCallScope()) {
// it's okay to call GetWindowText cross-thread.
//
int textLen = SafeNativeMethods.GetWindowTextLength(new HandleRef(window, Handle));
// Check to see if the system supports DBCS character
// if so, double the length of the buffer.
if (SystemInformation.DbcsEnabled) {
textLen = (textLen * 2) + 1;
}
StringBuilder sb = new StringBuilder(textLen + 1);
UnsafeNativeMethods.GetWindowText(new HandleRef(window, Handle), sb, sb.Capacity);
return sb.ToString();
}
}
set {
if (value == null) value = "";
if (!WindowText.Equals(value)) {
if (IsHandleCreated) {
UnsafeNativeMethods.SetWindowText(new HandleRef(window, Handle), value);
}
else {
if (value.Length == 0) {
text = null;
}
else {
text = value;
}
}
}
}
}
코드 MultithreadSafeCallScope
에서 의 사용에 유의하십시오 get
. 또한 Handle
크로스 스레드 오류를 발생 시키는 속성 의 사용에 유의하십시오 . 이 Handle
속성은 크로스 스레드 액세스를 확인 하는 게이트 키퍼 역할을 한다고 생각합니다 .
public IntPtr Handle {
get {
if (checkForIllegalCrossThreadCalls &&
!inCrossThreadSafeCall &&
InvokeRequired) {
throw new InvalidOperationException(SR.GetString(SR.IllegalCrossThreadCall,
Name));
}
if (!IsHandleCreated)
{
CreateHandle();
}
return HandleInternal;
}
}
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다