我有一个表格显示数据网格。我也有一个方法在不同的线程上运行,只更新网格中显示的单元格。为此,此方法在返回显示的单元格的窗体上调用一个函数。如何以线程安全的方式关闭表单(用于后台线程)?
我遇到的问题是,有时在表单被关闭和处置的情况下,另一个线程上的方法仍在调用这个函数,这会导致对象抛出的异常。有没有一种方法(其他则确保另一个线程的方法已完成)来防止这种情况发生?
所以我需要一个线程安全的方法来关闭表单时关闭后台任务。
private delegate List<foo> GetShownCellsDelegate();
public List<foo> GetShownCells()
{
if (this.InvokeRequired)
{
GetShownCellsDelegate getShownCellsDelegate = new GetShownCellsDelegate(GetShownCells);
return (List<foo>)this.Invoke(getShownCellsDelegate);
}
else
{
//do stuff
}
}
我尝试用表格的IsDisposed属性:
if (!IsDisposed)
{
return (List<foo>)this.Invoke(getShownCellsDelegate);
}
但显然形式可以if语句后dispossed因为我仍然得到isdisposed例外。
这是我如何使用其他线程的功能:
private CancellationTokenSource cts = new CancellationTokenSource();
public void CancelUpdate()
{
cts.Cancel();
}
public void ReadDataFromDevice()
{
ThreadPool.QueueUserWorkItem(new WaitCallback(ReadAllDataThreadPoolMethod));
}
private void ReadAllDataThreadPoolMethod(Object stateInfo)
{
if (!cts.IsCancellationRequested)
{
//do stuff
}
}
的CancelUpdate方法是从窗体上的IsClosing事件被调用。但我仍然有时会遇到遗漏的异常。
我编辑了我的问题以显示我是如何使用它的。有时我仍然会遇到异常情况。 –
@ Marc.O完全正确。我想,这应该是一场艰难的比赛条件,但它确实存在。请参阅编辑。 – Servy
但是,然后你阻塞线程,直到UI线程完成?我不认为这会发生,直到你关闭整个程序? –