跨线程操作无效:异步委托错误

本文关键字:错误 异步 线程 操作 无效 | 更新日期: 2023-09-27 18:13:08

我一直在努力学习委托。我刚刚创建了一个按钮、标签和复选框。单击"复选框"后,时间格式会发生变化。如果我点击按钮,我打印相应的日期。然而,当尝试使用异步委托,即使用另一个线程,我卡住了一个错误

   public delegate void AsyncDelegate(bool seconds);
public partial class Form1 : Form
{
    AsyncDelegate ad;
    TimeZ t = new TimeZ();
    public Form1()
    {
        InitializeComponent();
    }
 private void btn_async_Click(object sender, EventArgs e)
    {
        ad = new AsyncDelegate(t.GetTime);
        AsyncCallback acb = new AsyncCallback(CB);
        if (chk_sec.Checked)
        {
            ad.BeginInvoke(true, acb, null);
        }
        else
            ad.BeginInvoke(false, acb, null);

    }
    public void CB(IAsyncResult ar)
    {
        t.Tim = ar.ToString();
        ad.EndInvoke(ar);
        lbl_time.Text = t.Tim;
    }

和在另一个类库中,我得到上面使用的Timez。我在项目中添加了它的引用

 public class TimeZ
{
  private string tim;
    public string Tim
    {
        get
        {
            return tim;
        }
        set
        {
            tim = value;
        }
    }
    public string GetTime(bool seconds)
    {
        if (seconds)
        {
           return DateTime.Now.ToLongTimeString();
        }
        else
            return DateTime.Now.ToShortTimeString();
    }
}

然而,当我运行程序时,我得到这个错误:

 Cross-thread operation not valid: Control 'lbl_time' accessed from a thread other than   
    the thread it was created on.
你能告诉我怎么解决这个问题吗?

跨线程操作无效:异步委托错误

您不能从非表单线程访问表单和控件的属性和方法。

在窗口中,每个窗口都绑定到创建它的线程。

您只能在Control中这样做。BeginInvoke或更有用的System.Threading.SynchronizationContext类

见http://msdn.microsoft.com/it-it/library/system.threading.synchronizationcontext (v = vs.95) . aspx

见http://msdn.microsoft.com/it-it/library/0b1bf3y3 (v = vs.80) . aspx

这意味着,你必须通过同步上下文发布,例如在表单线程中另一个异步委托。

public partial class Form1 : Form
{
    AsyncDelegate ad;
    TimeZ t = new TimeZ();
    // Our synchronization context
    SynchronizationContext syncContext;
    public Form1()
    {
        InitializeComponent();
        // Initialize the synchronization context field
        syncContext = SynchronizationContext.Current;
    }
    private void btn_async_Click(object sender, EventArgs e)
    {
        ad = new AsyncDelegate(t.GetTime);
        AsyncCallback acb = new AsyncCallback(CB);
        if (chk_sec.Checked)
        {
            ad.BeginInvoke(true, acb, null);
        }
        else
        {
            ad.BeginInvoke(false, acb, null);
        }
    }
    public void CB(IAsyncResult ar)
    {
        // this will be executed in another thread
        t.Tim = ar.ToString(); // ar.ToString()???? this will not give you the time for sure! why?
        ad.EndInvoke(ar);
        syncContext.Post(delegate(object state)
        {
            // This will be executed again in form thread
            lbl_time.Text = t.Tim;
        }, null);
    }

我不知道为什么你需要一个异步回调来打印时间,但是:)真的不知道为什么,认为这只是一些测试代码。