苏飞论坛

 找回密码
 马上注册

QQ登录

只需一步,快速开始

分布式系统框架(V2.0) 轻松承载百亿数据,千万流量!讨论专区 - 源码下载 - 官方教程

HttpHelper爬虫框架(V2.7-含.netcore) HttpHelper官方出品,爬虫框架讨论区 - 源码下载 - 在线测试和代码生成

HttpHelper爬虫类(V2.0) 开源的爬虫类,支持多种模式和属性 源码 - 代码生成器 - 讨论区 - 教程- 例子

网站[高并发]下使用[静态方法]会造成页面无法访问的解决方案

查看数: 16738 | 评论数: 8 | 收藏 0
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2013-7-17 18:25

正文摘要:

先来说明一下问题,2楼开始说解决方案 委托delegate与Dictionary实现action选择器大家先看看我上一次的文章 大致如下 [C#] 纯文本查看 复制代码//定义一个委托    private delegate void actionByMain ...

回复

站长苏飞 发表于 2013-8-12 09:09:35
Dictionary本来就是不安全的,用静态,这不是火上加油么。看看这个吧,ConcurrentDictionary<TKey, TValue> 类

表示可由多个线程同时访问键/值对线程安全集合对。
aaaxjb 发表于 2013-7-23 00:51:58
你出现的情况 正好我也测试到了 ,  服务器上访问是活得,  客户端浏览器不能访问 。
你得第四点 我还没有实验 。
站长苏飞 发表于 2013-7-18 10:19:06
ConcurrentDictionary<TKey, TValue> 类

表示可由多个线程同时访问键/值对线程安全集合对。
站长苏飞 发表于 2013-7-18 08:37:08
[C#] 纯文本查看 复制代码
private static readonly object @lock = new Object();

public void ProcessRequest(HttpContext context)
   {
       string action = string.Empty;
       if (string.IsNullOrEmpty(context.Request["action"]))
       {
           return;
       }
       action = context.Request["action"];

       lock(@lock)
       {
       //先检查一下有没有这个action
       if (mainList.ContainsKey(action))
       {
           mainList[action](context); return;
       }
       }
   }

   //添加action对应方法的列表
   static void addMainList()
   {
     lock(@lock)
     {
       if(mainList.Count > 0)
       {
           return;
       }
       mainList.Add("post1", delegate(HttpContext context)
      {
          context.Response.Write("成功");
      });
       mainList.Add("post2", delegate(HttpContext context)
     {
         context.Response.Write("成功");
     });
       mainList.Add("post3", delegate(HttpContext context)
     {
         return;
     });
     }
   }

可以这样加锁,不过这样的效率很差。建议你采用无锁方案,比如ConcurrentDictionary
可以参考这里http://www.cnblogs.com/lulu/archive/2012/05/26/2519675.html

站长苏飞 发表于 2013-7-17 18:26:04
基本上可以判断是多线程冲突导致,你列举的几点都很符合多线程冲突场景。
第四点的话,可能是浏览器接收到IIS返回的错误信息,导致浏览器缓存了一些错误信息。具体问题,还需要你具体说明一下浏览器无法访问的错误信息。

static void addMainList() 这个方法是什么时候调用的?至少看起来不是静态构造函数,所以没有加锁的话,应该是会导致错误的。

if (mainList.ContainsKey(action))
       {
           mainList[action](context); return;
       }
mainList 应该不会因为回收导致为null,只要这个类还在运行,是不会回收的。但Dictionary本身不是线程安全的,所以这个用法有错。Dictionary的读写都不是线程安全的,包括ContainsKey方法。
站长苏飞 发表于 2013-7-17 18:25:56
高并发的时候才出问题,那是因为高并发的时候会出现多个线程同时操作mainList, 由于它不是线程安全的,所以就报错了! 加锁就是为了限制在一个线程操作它的时候,其他线程等待它操作完了再对它操作!
你这个mainList其实是很简单的字典而已,其实不要把它声明为static就不会有线程的安全问题!很多方法可以处理的,看你需要怎么用而已
站长苏飞 发表于 2013-7-17 18:25:43
[code=csharp]addMainList()是在什么地方调用的?构造函数?mainList是static的非线程安全的dictionary,增删改mainList的时候要加锁! 你这个例子,最简单的是把addMainList()放到静态构造函数里面调用 static ClassName
(){addMainList();}
或者增删改mainList的时候加锁
static object LockObj=new object();
static void addMainList()
{
lock(LockObj)
{
mainList.Add("post1", delegate(HttpContext context)
{
context.Response.Write("成功");
});
mainList.Add("post2", delegate(HttpContext context)
{
context.Response.Write("成功");
});
mainList.Add("post3", delegate(HttpContext context)
{
return;
});
}
}[/code]

QQ|手机版|小黑屋|手机版|联系我们|关于我们|广告合作|苏飞论坛 ( 豫ICP备18043678号-2)

GMT+8, 2025-7-3 15:05

© 2014-2021

快速回复 返回顶部 返回列表