本帖最后由 李维强-15级 于 2016-12-5 03:47 编辑
又是多线程,以前那次C++把我卡得差点不能给客户交货,这次这个卡了我两天。。。。现在我用取巧的办法解决了,但是任然不明其理。
事情是这样的,微信公众号里面需要全局缓存令牌盾,但是令牌盾是有过期时间的,而且每天有申请令牌盾的次数限制,所以我开个线程来做这个事情,然后在线程里面访问事先申请好了的全局变量,这样就可以弄了。但是在MVC架构里面申请全局变量是用的Application.Add("变量名", 0);这样来申请的(话说我只会这一种),然后在其他地方使用HttpContext.Current.Application["变量名"]这样来调用,进行读取和修改。
好了,我这里使用以下代码来做的
首先在Global.asax里面的Application_Start()里面定义一个变量,同样在这个函数里面开启线程。
[C#] syntaxhighlighter_viewsource syntaxhighlighter_copycode
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
Application.Add("gtest", 0);
acc_TokenClass mythread = new acc_TokenClass();
mythread.start();
}
然后在线程里面使用这个变量HttpContext.Current.Application["gtest"];
下面是线程的函数
[C#] syntaxhighlighter_viewsource syntaxhighlighter_copycode
namespace HTMLTest.myThread
{
public class acc_TokenClass
{
BaseDao basedao = new BaseDao();
Thread thread = null;
public bool isOpen = false
public void run()
{
while (true)
{
if (thread != null)
{
HttpContext.Current.Application["gtest"] = 5;
}
Thread.Sleep(60000 * 90);
}
}
public void start()
{
if (thread == null)
{
thread = new Thread(run);
isOpen = true;
thread.Start();
}
}
}
}
然后问题来了,在线程里面使用的时候发现HttpContext.Current直接是NULL,然后我百度,看到好多人都遇到这个问题,回头想想,这个也很正常,线程是独立资源嘛,不可能有主线程的东西的。下面就是如何解决,我看了网上的朋友,很多就是开委托,或者访问HttpRuntime,等情况。苦与我任务缠身,一直都没有去学C#,导致网上说的那些方法我都不会。
最后我采用了一种取巧的方法。
首先我在acc_TokenClass这个类里面定义一个变量public HttpContext context;然后在Application_Start()里面给这个变量赋值mythread.context = HttpContext.Current;这样就把当前的HttpContext.Current传到线程的那个类里面去了,然后在线程里面调用就一切正常了。
代码如下
[C#] syntaxhighlighter_viewsource syntaxhighlighter_copycode
protected void Application_Start()
{
.....
acc_TokenClass mythread = new acc_TokenClass();
mythread.context = HttpContext.Current; //这里把当前的current赋值过去
mythread.start();
}
[C#] syntaxhighlighter_viewsource syntaxhighlighter_copycode
namespace HTMLTest.myThread
{
public class acc_TokenClass
{
BaseDao basedao = new BaseDao();
Thread thread = null;
public bool isOpen = false
public HttpContext context; //这里在类里面定义一个变量
public void run()
{
while (true)
{
if (thread != null)
{
context.Application["gtest"] = 5; //这里直接调用赋值即可,我试了试可行的
}
Thread.Sleep(60000 * 90);
}
}
public void start()
{
if (thread == null)
{
thread = new Thread(run);
isOpen = true;
thread.Start();
}
}
}
}
最后我想问下各位,虽然我能够调用全局变量了,但是我这种方法会不会不对?会不会产生副作用?什么内存泄露什么的?
|