【发布时间】:2014-11-19 01:39:05
【问题描述】:
我有一个由事件处理程序启动的函数。在这个函数中,创建并运行了一个新任务来设置一个我稍后需要的全局变量,在另一个事件处理程序中。
这两个函数之间还有一些其他函数,它们不会更改其中使用的任何变量。但这就是它的样子。
private void EventWhereINeedTheGlobalVariableLater(object sender, Event e)
{
//...work...
need _variableIneed
//....more work...
}
private void EventWhereISetGlobalVariable(object sender, Event e)
{
//....work....
//...make cancellationToken...
//groups, isCommonalityGroup are other global variables already set.
Task.Factory.StartNew(() =>
{
// Clear variable to get new value
_variableIneed = null;
// Execute query to get new value
_variableIneed = _workingManager.GetValue(groups, isCommonalityGroup, cancellationToken);
RefreshView();
}, cancellationToken);
}
我遇到了竞争条件,其中我需要的变量_variableIneed 在第二个事件处理程序中为空,而它不能为空。如果我没有飞过并尝试创建足够的事件来使 wpf 程序崩溃,它工作正常,但即使我这样做,我也需要它工作。
我可以做些什么来克服这些竞争条件吗?
我尝试使用.ContinueWith 和OnlyOnRanToCompletion 选项或其他选项。还有什么我可以尝试的吗?
**注意,我无法更改事件的排序/处理/处理方式。这是一个漂亮的石头设计,我只需要解决它并或多或少地保持它的样子。
**更新
我也尝试过将ParallelExtensionsExtras 与OrderedTaskScheduler 类一起使用,但最终我仍然会得到我需要的变量的空引用。
【问题讨论】:
-
如果在
EventWhereISetGlobalVariable处理程序中设置变量之前调用EventWhereINeedTheGlobalVariableLater处理程序,您将无能为力。 -
你的意思是你在
EventWhereINeedTheGlobalVariableLater中得到空值?可能是Task没有完成?你需要同步它。 -
是的@SriramSakthivel 我得到了我需要的全局变量的空值。
-
这意味着
EventWhereISetGlobalVariable未被调用或StartNew创建的任务尚未完成。您可能需要调用task.Wait或await或ContinueWith来同步访问。但在访问之前仍然可能存在竞争(另一个任务已启动并将_variableIneed设置为null)。 -
@SriramSakthivel “可能会有比赛(另一个任务开始并设置......)这就是正在发生的事情。我能做些什么来解决这个问题?我试图避免使用
task.wait如果可能的话。
标签: c# wpf scheduled-tasks