为什么这种线程方法不起作用?

时间:2010-06-16 09:51:05

标签: c# .net asp.net vb.net multithreading

我在ASP.NET应用程序中遇到了一个奇怪的线程问题。出于某种原因,当我在请求线程中运行代码时,一切都按预期工作。但是当我在一个单独的线程中运行它时,没有任何反应 通过分别使用三个标志“on”,“off”和“larma”调用下面的处理程序来验证这一点 - 在前两种情况下一切正常,但后者没有任何反应。

我在这里做错了什么?

在Web项目中,我有一个包含以下代码的通用处理程序:

If task = "on" Then
    Alarm.StartaLarm(personId)
    context.Response.Write("Larmet är PÅ")
ElseIf task = "off" Then
    Alarm.StoppaLarm(personId)
    context.Response.Write("Larmet är AV")
ElseIf task = "larma" Then
    Alarm.Larma(personId)
    context.Response.Write("Larmar... (stängs av automagiskt)")
Else
    context.Response.Write("inget hände - task: " & task)
End If

Alarm类有以下方法:

Public Shared Sub Larma(ByVal personId As Integer)
    Dim thread As New System.Threading.Thread(New ParameterizedThreadStart(AddressOf Larma_Thread))
    thread.Start(personId)
End Sub

Private Shared Sub Larma_Thread(ByVal personId As Integer)
    StartaLarm(personId)
    Thread.Sleep(1000 * 30)
    StoppaLarm(personId)
End Sub

Public Shared Sub StartaLarm(ByVal personId As Integer)
    SandSMS(True, personId)
End Sub

Public Shared Sub StoppaLarm(ByVal personId As Integer)
    SandSMS(False, personId)
End Sub

Public Shared Sub SandSMS(ByVal setOn As Boolean, ByVal personId As Integer)
    ...
End Sub

UPDATE / CLARIFICATION:在调用线程版本时,我仍然得到对客户端的预期响应 - 没有错误消息。

我还在上面的代码中包含了一个被遗忘的方法。

更新2: @Henk,不幸的是我没有调试能力,因为这个问题只出现在我们的服务器上,它没有安装Visual Studio并且不允许远程调试。

但是,SendSMS方法会向我的手机发送短信,短信网络服务和我的手机同意在拨打“开”或“关”时发送短信,但在拨打电话时则不会larma”。

因为我知道整个链Handler-> StartaLarm - > SandSMS(True/False)适用于“on”和“off”,所以我必须假设故障发生在Handler->的某个地方。 Larma - > Larma_Thread,因此是一个线程问题。

更新3 :@Vadmyst,将您的代码转换为VB.NET(这不是我最喜欢的两个,但是这个项目需要它......)并修改它来编译,我到达了以下(虽然我不是100%肯定它仍然意味着同样的事情......):

ThreadPool.QueueUserWorkItem(New WaitCallback(Function(p As Integer) Larma_Thread(p)))

没有成功 - 我有与上面相同的结果...... =(

4 个答案:

答案 0 :(得分:1)

记录是你的朋友。如果你要发送短信,你应该在尝试之前当然进行记录,或者在你完成之后(或者没有做到)。

对于此特定问题,我建议您在启动线程之前和之后添加日志记录(或将任务提交到线程池)。基本上,你输入的日志越多(当然暂时)你就会有更多的想法。

重要的是,请确保记录引发的任何异常。您还应查看IIS日志,以查看是否有任何异常记录。

答案 1 :(得分:1)

在SandSMS中有一个异常,在一个辅助线程的上下文中从Larma_Thread调用StartaLarm调用。多线程应用程序中的“没有发生”行为是次要线程中异常的强烈指示。首先想到的是,在Web应用程序中的非请求线程中,不同的是非请求线程无法访问诸如当前HttpContext和Session之类的内容。

答案 2 :(得分:0)

SendSMS是否依赖于任何ASP.NET内部的东西? 尝试使用ThreadPool启动Larma_Thread。

我不是VB大师,会尝试在C#

上使用ThreadPool编写示例
public static void Larma(int personId)
    {
        ThreadPool.QueueUserWorkItem(new WaitCallback(
            delegate(object unused)
            {
                try
                {
                    Larma_Thread(personId);
                }
                catch { /*log here */}
            }), personId);
    }

答案 3 :(得分:0)

我不知道这是否重要,但你是参与化线程启动的委托不是正确的原型。它应该如下:

<ComVisibleAttribute(False)>
Public Delegate Sub ParameterizedThreadStart ( obj As Object )

您使用输入类型int定义它,不知道这里会发生什么。

有关详细信息,请参阅MSDN上的这篇文章:

ParameterizedThreadStart Delegate