【发布时间】:2012-09-14 00:21:21
【问题描述】:
我有一个绑定到 datgridview 的 BindingList 数据。我用它来跟踪一些实时价格。各种线程每秒多次调用方法“update(Quote quote)”。如果 datagridview 不包含引用,则添加它。如果是,则更新报价的值。我不希望相同的引号出现在 BindingList (或 GUI 上)两次,所以我尝试锁定检查值是否在列表中的操作。它不起作用!我究竟做错了什么?我尝试了两种不同的锁定方式,并且锁定在 String 对象上,而不仅仅是一个对象。问题肯定出在BeginInvoke(new MethodInvoker(delegate() { activeQuotes.Insert(0, quote); })); 调用中(这可能需要一些时间),但如果我进行同步,“add”方法会引发“cross-threading”错误。 . .我可以做些什么来避免跨线程错误,但确保锁也可以工作??
public BindingList<Quote> activeQuotes = new BindingList<Quote>();
object lockObject = "lockObject";
dataGridViewActive.DataSource = activeQuotes;
public void update(Quote quote)
{
//lock (lockObject)
if(Monitor.TryEnter(lockObject))
{
try
{
if (!activeQuotes.Contains(quote))
{
try
{
activeQuotes.Add(quote);
AddQuote(quote);
}
catch (Exception ex)
{
Console.WriteLine("Datagridview!!!!!!");
}
}
else
{
int index = activeQuotes.IndexOf(quote);
activeQuotes[index].Bid = quote.Bid;
activeQuotes[index].Ask = quote.Ask;
activeQuotes[index].Mid = quote.Mid;
activeQuotes[index].Spread = quote.Spread;
activeQuotes[index].Timestamp = quote.Timestamp;
}
finally
{
Monitor.Exit(lockObject);
}
}
private void AddQuote(Quote quote)
{
if (this.InvokeRequired)
{
BeginInvoke(new MethodInvoker(delegate() { activeQuotes.Insert(0, quote); }));
BeginInvoke(new MethodInvoker(delegate() { dataGridViewActive.Refresh(); }));
BeginInvoke(new MethodInvoker(delegate() { dataGridViewActive.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells); }));
}
else
{
activeQuotes.Add(quote);
dataGridViewActive.Refresh();
dataGridViewActive.AutoResizeColumns (DataGridViewAutoSizeColumnsMode.AllCells);
}
}
如果能提供任何帮助,我将不胜感激。
谢谢。
【问题讨论】:
标签: c# asynchronous locking multithreading