2010-06-16 86 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

相關問題