我制作了一个简单的网页。当使用querystring调用它时,它会增加应用程序变量。3秒后,线程结束时变量减小。
问题是,当我打开2个资源管理器页面(或mozilla)并从一个页面调用页面并从另一个页面获取结果时,一切都很好。但当我使用多线程测试应用程序进行200次或更多的调用时,数字不会返回到零。它永远不会像240或20那样保持在同一个数字。每次都不同,但不是零。
page_load事件准备自动处理。我的多线程应用程序像http://localhost:4444/test.aspx?i=anything
一样调用这个页面,所以页面automaticallu向变量"x"添加1并启动线程。变量应该在3秒后减1,总和应该变为零。但不是???
重要提示:当我在测试应用程序中使用1个线程来调用这个网页时,它"基本上"工作正常。例如,它有时会上升到680并返回到零。若我使用两个线程来调用页面,那个么结果"总是"不一致。
有趣的是,如果我使用sql server并将变量保持在那里,并使用增加/减少,那么就不用应用程序变量了
UPDATE test SET count=count + 1
UPDATE test SET count=count - 1
我认为即使同时连接20个也没有问题。
有什么建议吗?
Partial Class test
Inherits System.Web.UI.Page
Dim _resetEvent As New AutoResetEvent(False)
Protected Sub cmdWriteVariable_Click(sender As Object, e As EventArgs) Handles cmdWriteVariable.Click
Response.Write(Application("x").ToString)
End Sub
Protected Sub cmdIncreaseValue_Click(sender As Object, e As EventArgs) Handles cmdIncreaseValue.Click
If Application("x") Is Nothing Then Application("x") = 0
Application.Lock()
Application("x") = CInt(Application("x").ToString) + 1
Application.UnLock()
Response.Write(Application("x").ToString)
End Sub
Protected Sub Async_start()
Dim workerObject As New myTestAsyncClass(_resetEvent)
workerObject.ad = "anyname"
Dim ctx As HttpContext = HttpContext.Current
Dim workerThread As New Thread(New ThreadStart(Sub()
HttpContext.Current = ctx
workerObject.DoWork2(ctx)
End Sub))
workerThread.Start()
End Sub
Protected Sub cmdReset_Click(sender As Object, e As EventArgs) Handles cmdReset.Click
Application("x") = 0
End Sub
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
If Application("x") Is Nothing Then Application("x") = 0
If Request.QueryString("i") IsNot Nothing Then
Application.Lock()
Application("x") = CInt(Application("x").ToString) + 1
Application.UnLock()
Async_start()
End If
End Sub
End Class
这是线程类:
Imports Microsoft.VisualBasic
Imports System.Threading
Public Class myTestAsyncClass
Dim _resetEvent As AutoResetEvent = Nothing
Public ad As String
Public Sub New(resetEvent As AutoResetEvent)
_resetEvent = resetEvent
End Sub
Public Sub DoWork2(state As Object)
Try
Dim context As HttpContext = TryCast(state, HttpContext)
System.Threading.Thread.Sleep(3000)
Dim x As Integer = CInt(context.Application("x").ToString)
x = x - 1
context.Application.Lock()
context.Application("x") = x.ToString
context.Application.UnLock()
Finally
_resetEvent.[Set]()
End Try
End Sub
End Class
和aspx页面以防万一:它的简单的3个按钮。写入变量,重置为零并增加1。打开2个资源管理器,多次单击"增加",然后从其他资源管理器单击"写入变量"按钮。你会看到它工作得很好。增加到,比方说10,3秒后变量变为零。
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="test.aspx.vb" Async="true" Inherits="test" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="cmdIncreaseValue" runat="server" Text="increasevalue" />
<br />
<br />
<asp:Button ID="cmdWriteVariable" runat="server" Text="write app variable" />
<br />
<br />
<asp:Button ID="cmdReset" runat="server" Text="set varable to 0" />
</div>
</form>
</body>
</html>
嗯,我相信我在这里找到了:
我希望有一天它能帮助到别人。
最好的。。
http://stackoverflow.com/questions/25358448/why-my-httpcontext-application-variable-cannot-be-access-through-different-actio
说:
Disadvantages of Application State:
Application scope The scope of application state can also be a disadvantage.
Variables stored in application state are global only to the particular process the
application is running in, and each application process can have different values.
Therefore, you cannot rely on application state to store unique values or update global
counters in Web-garden and Web-farm server configurations.