UPDATE:跨线程操作无效 - DataGridView的更新数据源
我使用“FileSystemWatcher的”要监视的对象文件,当它调用onChanged事件触发时,我把它作为一个提示更新我的DataGridView 。然而,在这样做时,我得到了以下错误:“跨线程操作无效:控制'dgvSession'从其创建线程以外的线程访问”。现在,在对这个错误进一步研究后,很明显应该使用一个对象的Completed事件,重点在于它应该是在操作完成后触发的事件。 FileSystemWatcher只有一个OnChanged事件并且用它更新数据网格视图不起作用 - 所以我跟着this linktoadflakz给了我并实现了一个静态类来使用扩展方法来线程安全地设置我的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 ||
[email protected]().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表达式‘财产’必须引用此控件上的有效属性“。似乎我所采取的行动并未在扩展方法的第一个IF语句中检查出来。
“这样就解决了我的问题” - 我不认为它会。问题是要处理您正在使用的线程,而不是文件是否已完成更新。 – 2014-11-21 16:58:29