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