开发者

Using Control.Invoke() in place of lock(Control)

I am working on a multi-threaded application which needs to update a Winforms control as it progresses (A DataGridView). In order to prevent multiple access to the same shared resource, I started out with the following lock structure:

if (DGV.Columns.Count >= DesiredColumnCount) return;
lock(DGV)
{
    while (DGV.Columns.Count < DesiredColumnCount)
    {
        DGV.Columns.Add(newColumn);
    }
}

I then realized that, since the DGV was created on the UI thread, it needs to be .Invoke()'d. This changes the code to:

if (DGV.Columns.Count >= DesiredColumnCount) return;
lock(DGV)
{
    DGV.Invoke(new MethodInvoker(() =>
        {
            while (DGV.Columns.Count < DesiredColumnCount)
            {
                DGV.Columns.Add(newColumn);
            }
        }
}

My question is: Isn't this redundant? the lock will block the worker thread until it has exclusive access开发者_StackOverflow中文版 to DGV, and the Invoke() will block the worker thread until the UI thread can pick up the invoke request and execute the code. Can't I just get by using only the Invoke()?

(That is the main question. Of course if there are any other multithreading sins in the above code, please comment)


It is a bit redundant, the Invoke call will "dispatch" the operpation to the UI thread. Each subsequent Invoke call will be dispatched in a serial fashion, so there isn't really any need to do any locking.

You may consider using BeginInvoke instead of Invoke order to prevent the worker thread from blocking, but again, that will be done "serially" so there is no need to worry about locking.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜