我有一个由事件处理程序启动的函数。在此函数中,创建并运行一个新任务以设置稍后在另一个事件处理程序中需要的全局变量。
这两个函数之间还有一些其他函数,它们不会更改其中使用的任何变量。但它看起来是这样的。
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);
}
我遇到了竞争条件,我需要的变量 _variableIeed
在第二个事件处理程序中为 null,但它不能为 null。如果我没有飞过并尝试创建足够的事件来崩溃 wpf 程序,它就可以正常工作,但即使我这样做,我也需要它工作。
我可以做些什么来克服这些竞争条件吗?
我尝试将 .ContinueWith
与 OnlyOnRanToCompletion
选项或其他选项一起使用。我还可以尝试其他事情吗?
**注意,我无法对事件的排序/处理/处理方式进行太多更改。这是一套漂亮的石头设计,我只需要解决它并保持它或多或少的样子。
**更新
我还尝试将 ParallelExtensionsExtras
与 OrderedTaskScheduler
类一起使用,但最终仍然得到我需要的变量的空引用。
最佳答案
当您有一个任务
来生成值时,不要将结果设置为全局变量,而是将该结果作为任务的结果
,并将其存储起来任务。当其他代码稍后需要该结果时,它可以从任务中获取它。这将允许 Task
类处理所有复杂的同步逻辑,防止在任务实际计算结果之前使用结果,等等。
当然,对于需要使用结果的事件,它可能不需要阻止该任务,而是在任务完成后异步执行需要结果的其余代码。通过对该任务使用 await
可以非常轻松地完成此操作。如果您仅使用 .NET 4.0,则可以显式使用 ContinueWith
。
关于c# - C# 任务和全局变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26018968/