2012-02-13 714 views
3

我有一个应用程序与文本框,我需要从多个线程更新文本框。由于我正在更新多线程的文本框,我正在使用以下代码来确保它在主线程中被调用(如果有必要) - 但即使使用此代码,我仍然收到错误 - 特别是“对象当前正在其他地方使用” 。'对象正在使用其他'错误InitializeComponent和调用/锁

,我使用的代码:

private static readonly object setTextLockObject = new object(); 
delegate void SetTextCallBack(XtraForm Form, string ControlToUpdate, string ControlValue); 

public void UpdateControlText(XtraForm Form, string ControlToUpdate, string ControlValue) 
{ 
    try 
    { 
     if (Form.Controls[ControlToUpdate].InvokeRequired) 
     { 
      SetTextCallBack callBackHandler = UpdateControlText; 
      IAsyncResult invokeResult = Form.Controls[ControlToUpdate].BeginInvoke(callBackHandler, Form, ControlToUpdate, ControlValue); 
      Form.Controls[ControlToUpdate].EndInvoke(invokeResult); 
     } 
     else 
     { 
      try 
      { 
       lock (setTextLockObject) 
       { 
        Form.Controls[ControlToUpdate].Text = ControlValue.Translate(); 
       } 
      } 
      catch (Exception x) 
      { 
       UpdateStatus(string.Format("ControlText1: {0} ControlToUpdate={1}ControlText={2}", x.Message, ControlToUpdate, ControlValue)); 
      } 
     } 
    } 
    catch (Exception ex) 
    { 
     UpdateStatus(string.Format("ControlText2: {0} ControlToUpdate={1} ControlText={2}", ex.Message, ControlToUpdate, ControlValue)); 
    } 
} 

我更新与调用该文本,并确保锁定对象,以便另一个线程不应该能够访问onject同时被更新。我期望第二个线程等待锁释放,但我得到的“对象目前正在使用”。有人能帮我理解我在这里做错了吗?

我有一个更大的问题,当在窗体上做一个应用程序调用 - 在InitializeComponent我也得到“对象目前正在其他地方使用”。这是一个新的对象,并没有在其他地方使用。为什么初始化组件时可能会出现此错误?

at System.Drawing.Graphics.get_PageUnit() 
at DevExpress.Utils.Text.FontsCache.GetFontCacheByFont(Graphics graphics, Font font) 
at DevExpress.Utils.Text.FontsCache.GetStringSize(Graphics graphics, String text, Font font, StringFormat stringFormat, Int32 maxWidth) 
at DevExpress.Utils.Text.TextUtils.GetStringSize(Graphics g, String text, Font font, StringFormat stringFormat, Int32 maxWidth) 
at DevExpress.Utils.Paint.XPaintMixed.CalcTextSize(Graphics g, String s, Font font, StringFormat strFormat, Int32 maxWidth) 
at DevExpress.Utils.AppearanceObject.CalcTextSize(Graphics g, StringFormat sf, String s, Int32 width) 
at DevExpress.XtraEditors.ViewInfo.LabelControlViewInfo.CalcSimpleTextSize(String Text, Boolean useHotkeyPrefix, LabelAutoSizeMode mode, Int32 predWidth) 
at DevExpress.XtraEditors.ViewInfo.LabelControlViewInfo.CalcTextSize(String Text, Boolean useHotkeyPrefix, LabelAutoSizeMode mode, Int32 predWidth) 
at DevExpress.XtraEditors.LabelControl.GetPreferredSize(Size proposedSize) 
at DevExpress.XtraEditors.LabelControl.SetBoundsCore(Int32 x, Int32 y, Int32 width, Int32 height, BoundsSpecified specified) 
at System.Windows.Forms.Control.System.Windows.Forms.Layout.IArrangedElement.SetBounds(Rectangle bounds, BoundsSpecified specified) 
at System.Windows.Forms.Layout.CommonProperties.SetAutoSize(IArrangedElement element, Boolean value) 
at System.Windows.Forms.Control.set_AutoSize(Boolean value) 
at DevExpress.XtraEditors.LabelControl.set_AutoSizeMode(LabelAutoSizeMode value) 
at AccessControl.frmRefillCard.InitializeComponent() 

任何援助将不胜感激。

+0

你不要被方式需要输入锁 - 因为一切都在这一点上在单UI线程正在发生的事情,你不能让多个线程访问文本一次。 – 2012-02-13 01:18:12

回答

0

我认为你通过在UI线程上调用UpdateControlText方法来使事情复杂化。当你连续打电话给他们时,BeginInvokeEndInvoke也没有意义。

如何:

public void UpdateControlText(XtraForm Form, string ControlToUpdate, string ControlValue) 
{ 
    if (Form.Controls[ControlToUpdate].InvokeRequired) 
    { 
     try 
     { 
      Form.Controls[ControlToUpdate] 
       .Invoke(() => Form.Controls[ControlToUpdate].Text = ControlValue.Translate()); 
     } 
     catch (Exception x) 
     { 
      UpdateStatus(string.Format("ControlText1: {0} ControlToUpdate={1}ControlText={2}", 
       x.Message, ControlToUpdate, ControlValue)); 
     } 
    } 
}