我有一个网格控件,点击每一行做一些后台工作来加载数据。每个后台作业都在线程池线程上执行。当用户快速点击项目时,许多加载数据的请求将排队。我希望通过在单击每一行后提供延迟来最小化这一点。在触发加载数据的请求之前会有一些延迟。
我正在考虑使用DispatcherTimer类。像,
readonly DispatcherTimer dt = new DispatcherTimer();
private void Clicked(object sender, RoutedEventArgs e)
{
dt.Interval = TimeSpan.FromSeconds(2);
dt.Stop();
dt.Start();
}
private void DtOnTick(object sender, EventArgs args)
{
// Fire a thread and do data loading
}
这是解决问题的正确方法吗?
任何建议都将不胜感激!
答案 0 :(得分:1)
如果在作业完成之前禁用控件怎么样?或者一旦要完成的作业队列达到一定大小就禁用?这将是一个简单的解决方案,以防止用户“点击太多”。这样,延迟就会随着计算机解决方案/速度的提高而扩展。
答案 1 :(得分:1)
你试图这样做的方法只是将问题本身延迟2秒。所有的点击只会在两秒后处理。
您可能尝试使用工作线程。假设您使用一个队列来获取有关单击时单击的每个项目的信息。创建类时创建的现有线程会在将新项添加到队列时得到通知。线程获取第一个项目,处理它,更新UI。如果有更多项目,则需要下一个项目,处理它等等。当没有更多项目时,线程将进入休眠状态,直到有新项目可用(ManualResetEvent
将有助于此处。)
模式是:
void ItemClicked(...)
{
lock (WorkQueue)
{
QueueNewClickItem(...);
m_workToDo.Set();
}
}
void WorkerThread(...)
{
bool threadShouldEnd = false;
while (!threadShouldEnd)
{
if (WaitHandle.WaitAny(m_workToDo, m_endThread) == 0)
{
lock (WorkQueue)
{
CopyAllPendingWorkItemsToListInThread();
ClearWorkQueue();
m_workToDo.Reset();
}
while (!AllLocalItemsProcessed)
{
ProcessNextWorkItem();
}
}
else
{
threadShouldEnd = true;
}
}
}
答案 2 :(得分:0)
你真正想做的是这样的事情:
private DateTime? _NextAllowedClick;
private void Clicked(object sender, RoutedEventArgs e)
{
if (_NextAllowedClick != null && DateTime.Now < _NextAllowedClick)
{
return;
}
_NextAllowedClick = DateTime.Now + new TimeSpan(0, 0, 0, 2);
...
}