开发者

Rule of the Cross-Thread operation exception?

I'm looking for a rule to know which properties of a Control prevent accessing from other threads than the thread it was created on. (say UI thread) In other words, why is it possible to access some p开发者_如何学编程roperties of a Control from any arbitrary thread while some other ones refuse it?

:
:
{
    Thread thrd1 = new Thread(DoSomething);
    thrd1.Start();
}
:
:
void DoSomething()
{
    // There is no problem..
    dataGridView1[columnIndex1, rowIndex1].Value = "Access is free!";
    dataGridView1[columnIndex1, rowIndex1].Style.BackColor = Color.Red;

    // Cross-Thread operation exception would be thrown..
    dataGridView1.Rows[rowIndex1].Visible = false;
}
:
:

Thanks


Basically anything whose implementation involves a window handle has affinity with the thread that created that window handle. This restriction is inherited from the underlying Windows API.

Since you can't know the implementation, you have to assume that everything needs Invoke unless the documentation specifically calls out an exception.


While some properties don't require synchronized access, you shouldn't rely on this behavior unless the documentation for the property clearly indicates that the properties may be accessed from any thread. Use Control.InvokeRequired to conditionally perform a cross-thread invocation.

For example:

void DoSomething()
{
    if (dataGridView1.InvokeRequired)
        dataGridView1.Invoke(new Action(DoSomethingImpl));
    else
        DoSomethingImpl();
}

void DoSomethingImpl()
{
    dataGridView1[columnIndex1, rowIndex1].Value = "Access is free!";
    dataGridView1[columnIndex1, rowIndex1].Style.BackColor = Color.Red;

    dataGridView1.Rows[rowIndex1].Visible = false;
}

I like to encapsulate this functionality like so:

public static object AutoInvoke(
    this ISynchronizedInvoke self,
    Delegate del,
    params object[] parameters)
{
    if (self == null)
        throw new ArgumentNullException("self");

    if (del == null)
        throw new ArgumentNullException("del");

    if (self.InvokeRequired)
        return self.Invoke(del, parameters);
    else
        return del.DynamicInvoke(parameters);
}

Then DoSomething() becomes:

void DoSomething()
{
    dataGridView1.AutoInvoke(new Action(DoSomethingImpl));
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜