首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >由于堆栈为空,Parallel.Invoke内的DataBind()失败。错误

由于堆栈为空,Parallel.Invoke内的DataBind()失败。错误
EN

Stack Overflow用户
提问于 2011-07-28 08:29:07
回答 2查看 1.1K关注 0票数 2

我不确定为什么这个错误会间歇性地发生。我有一个并行绑定数据的UserControl。代码在90%的时间内都能正常工作,但有时数据库绑定会失败,并收到下面的错误。

代码语言:javascript
运行
复制
   at System.Collections.Stack.Pop()
   at System.Web.UI.Control.DataBind(Boolean raiseOnDataBinding)
   at System.Web.UI.WebControls.Repeater.CreateItem(Int32 itemIndex, ListItemType itemType, Boolean dataBind, Object dataItem)
   at System.Web.UI.WebControls.Repeater.CreateControlHierarchy(Boolean useDataSource)
   at System.Web.UI.WebControls.Repeater.OnDataBinding(EventArgs e)

有人知道为什么会发生这种情况,以及如何避免吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-07-28 16:38:14

这是一个并发问题。web控件are not guaranteed to be type-safe上的实例方法。因此,不应该在多个线程上同时调用DataBind (和其他实例方法)。

至于发生这种情况的原因:Control class implementation包含一个内部Page实例;该实例有一个用于数据绑定的内部堆栈。

代码语言:javascript
运行
复制
protected virtual void DataBind(bool raiseOnDataBinding) {
    bool inDataBind = false;
    if (foundDataItem && (Page != null)) { 
        Page.PushDataBindingContext(dataItem);
        inDataBind = true;
    }
    try{
    //...
    } finally {
        if (inDataBind) { 
            Page.PopDataBindingContext(); 
        }
    }
}

通常,每次推送都会伴随着后来的弹出,以确保堆栈永远不会为空。但是,Stack类本身是基于数组的,数组在填充时被复制到更大的数组中。如果在复制数组时同时推送多个值,则在某些情况下,复制操作可能会执行两次,所有操作都会丢失。当在PushDataBindingContext上下文中发生这种情况时,数据项实际上永远不会被推送到堆栈--当该方法稍后尝试从堆栈中弹出它推送的项时,堆栈是空的,并且会抛出异常。

票数 2
EN

Stack Overflow用户

发布于 2011-07-28 09:04:49

异常很可能是线程安全问题。特别是,如果你有多个线程并行运行这样的代码:

代码语言:javascript
运行
复制
// s is a instance of Stack
if (s.Count > 0)
     s.Pop()

堆栈可以由s.Counts.Pop()调用之间的另一个线程清空。由于堆栈为空,因此对s.Pop()的后续调用失败。

在C# 4中,一种(推荐的)替代方案是使用System.Collections.Concurrent.ConcurrentStack来代替Stack。这个类包括方法TryPop,如果堆栈不为空,它将返回堆栈中的顶部项(作为输出参数),否则返回false。因为进程是原子的,所以操作是线程安全的。

第二种选择是使用SyncRoot属性锁定堆栈:

代码语言:javascript
运行
复制
lock(s.SyncRoot)
{
    if (s.Count > 0)
       s.Pop();
}

这将防止多个线程同时从堆栈中删除项。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6852857

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档