2010-06-16 84 views
0

我有一个奇怪的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 /澄清:我仍然得到在调用线程版本时对客户端的预期响应 - 无错误消息。

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

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

但是,SendSMS方法会向我的手机发送文本消息,并且文本消息Web服务和我的电话都同意在调用“on”或“off”时发送消息,但不会在调用“larma”时发送消息。

因为我知道,整个链条Handler->StartaLarm - >SandSMS(True/False)作品“开”和“关”,我必须假设,在Handler->Larma某处出现故障 - >Larma_Thread,因而是一个穿线问题。

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

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

没有成功 - 我也有同样的结果如上... =(

+0

这一澄清说线程版本的工作? – 2010-06-16 11:42:51

+0

@亨克:没有 - 没有工作,只是没有给出任何错误。正如您在代码中看到的,我启动了一个不同的线程来执行这些任务,然后向客户端返回一个字符串。字符串被返回,但是任务没有被执行。对不起,没有更清楚。 – 2010-06-16 12:01:49

+0

你是否让Denug找出2个SendSMS调用是否被实际执行? – 2010-06-16 13:51:19

回答

1

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

+0

+1正如我的想法。日志记录将有所帮助,同样可以设置SendSMS所需的任何线程本地上下文 – mdma 2010-06-23 21:48:13

+0

这很愚蠢,但就是这样。我在一个非常长的行(由于字符串字面意思而已)的末尾调用了'HttpContext.Current ...',把它搞砸了。非常感谢! – 2010-06-26 19:58:23

0

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

我不是一个VB大师,并会尝试写与线程池的样品在C#

public static void Larma(int personId) 
    { 
     ThreadPool.QueueUserWorkItem(new WaitCallback(
      delegate(object unused) 
      { 
       try 
       { 
        Larma_Thread(personId); 
       } 
       catch { /*log here */} 
      }), personId); 
    } 
+0

在使用http://www.developerfusion.com/tools/convert/csharp-to-vb/转换为VB之后,我在第1行的'Function'中得到一个错误(转换为查看我的意思),说“这种类型的在VB 9.0中不支持lambda表达式“。这是否应该在.NET中工作<4? – 2010-06-21 13:33:04

+0

这是匿名方法。他们在那里介绍了.NET 2.0 – 2010-06-21 13:59:24

1

记录在这里你的朋友。如果你正在发送短信,你应该在尝试之前以及完成之后(或者未能完成)记录日志。

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

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

0

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

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

你有它定义一个输入类型的int,不知道这里会发生什么。

请参阅本文MSDN上了解更多信息:

ParameterizedThreadStart Delegate

相关问题