跨线程操作无效 - DataGridView更新数据源

时间:2014-11-21 16:55:50

标签: c# multithreading datagridview

更新:

我正在使用'FileSystemWatcher'对象来监视文件,当它的OnChanged事件触发时,我将它用作更新我的DataGridView的提示。但是,在这样做时,我收到以下错误:“跨线程操作无效:控制'dgvSession'从其创建的线程以外的线程访问”。现在,在对该错误进行进一步研究后,很明显应该使用一个对象的Completed事件,并强调它应该是一个操作完成后触发的事件。 FileSystemWatcher只有一个OnChanged事件并且用它来更新数据网格视图不起作用 - 所以我跟着this link给了我toadflakz并实现了一个静态类来使用扩展方法来线程安全设置我的datagridview的数据源。这是静态类:

public static class CThreadSafe
{
    private delegate void SetPropertyThreadSafeDelegate<TResult>(Control @this, Expression<Func<TResult>> property, TResult value);

    public static void SetPropertyThreadSafe<TResult>(this Control @this, Expression<Func<TResult>> property, TResult value)
    {
        var propertyInfo = (property.Body as MemberExpression).Member as PropertyInfo;

        if (propertyInfo == null ||
            !@this.GetType().IsSubclassOf(propertyInfo.ReflectedType) ||
            @this.GetType().GetProperty(propertyInfo.Name, propertyInfo.PropertyType) == null)
        {
            throw new ArgumentException("The lambda expression 'property' must reference a valid property on this Control.");
        }

        if (@this.InvokeRequired)
        {
            @this.Invoke(new SetPropertyThreadSafeDelegate<TResult>(SetPropertyThreadSafe), new object[] { @this, property, value });
        }
        else
        {
            @this.GetType().InvokeMember(propertyInfo.Name, BindingFlags.SetProperty, null, @this, new object[] { value });
        }
    }
}

但是,在使用此扩展方法设置属性时:

DataTable tblSession = new DataTable();

string sql = "SELECT * FROM crosssession ORDER BY MemberID";
MySqlDataAdapter daSession = new MySqlDataAdapter(sql, cnSession);

daSession.Fill(tblSession);
dgvSesssion.SetPropertyThreadSafe(() => dgvSesssion.DataSource, tblSession);

我陷入静态类的ArgumentException:“lambda表达式'property'必须引用此Control上的有效属性”。看起来我正在采取的行动不会在扩展方法的第一个IF语句中检出。

1 个答案:

答案 0 :(得分:2)

确保您从正确的主题更新UI控件。 FileSystemWatcher将在不是UI线程的线程上引发事件。

通常,这意味着您需要在UI托管类上创建一个界面,以检查在更新DataGridView之前是否可以访问Control

可以在此处找到执行检查和调用所需的代码:How to update the GUI from another thread in C#?

相关问题