簡體   English   中英

有沒有一種方法可以強制應用程序以單線程運行?

[英]Is there a way to force the application to run as single threaded?

我們有一個正在支持的舊項目,並且最有可能是由於多線程導致的問題出現。 原始實現者通過在執行有問題的部分之前執行Thread.sleep來“修復”它。 解決方法是thread.sleep但由於該節位於循環中,因此thread.sleep使該節完成所需的時間增加了幾分鍾。

在上個月,我們一直在嘗試使用較低的睡眠值,但我們希望找到根本原因。 在我們的調查過程中,我們會lock任何我們認為有幫助的私人對象。 我們尋找可能產生其他線程的任何內容-沒有找到。 沒有Thread.start,也沒有使用ThreadPool。 讓我們感到困惑的是,在調試過程中,我們發現我們的主線程位於其他8個線程的中間,我們不知道是誰產生了它們。 這些是后台線程,因此我首先以為我是線程池,但是正如我在代碼中沒有提到的那樣。

它是.net 2.0,因此沒有Async 這只是較大應用程序的一部分,因此它是Windows服務,但我們將其作為CMD運行,以便能夠輕松對其進行調試。主要應用程序本身是Windows Forms桌面應用程序。 如果有幫助的話,它也使用COM +組件。

我嘗試使用[STA]而不是[MTA] 也如上所述鎖定。 以及MemoryBarrier

我們仍然遇到問題。

問題本質上是數據集損壞,對象不應為空。 它大約每25-100次迭代發生一次,因此重現並非一帆風順,但我們專門針對此問題設計了一個測試來嘗試重現它。

所有這些都將我們引向了線程問題的方向。

回到最初的問題-誰可能通過產生這些額外的線程來解決這些問題,以及如何防止創建這些線程?

在此處輸入圖片說明

請注意標記為紅色的線程-這些是后台線程,據我們所知在代碼中沒有提及它們。

屏幕截圖中的可疑線程正在積極修改dataset的cols。 問題是-線程正在執行的調用SetColValueOnRow函數的方法很典型,並且不使用任何類型的線程。

此應用程序的CPU關聯性設置為1核心[原始替代方法的一部分]

謝謝

編輯:數據庫是oracle 12c,但是我們面臨的問題是在寫入數據庫之前發生的。 它們通常發生在DataSets中,每執行幾次測試迭代,就可以擦除整個記錄或其中的一些列

我認為您需要研究Thread.sleep為什么起作用。 聽起來好像代碼本身並沒有產生額外的線程,但是您必須遍歷整個代碼庫才能找到答案-包括COM +組件。

因此,我要做的第一件事是在調試中啟動程序,然后按F10鍵進入程序。 然后打開線程調試窗口,看看是否看到與問題數量相同的線程數。 如果這樣做,那么這些只是線程池中的線程,您的問題可能與多個線程無關。

如果看不到相同數量的線程,請嘗試在程序的各個階段設置一個斷點,看看是否可以找到在哪里創建這些線程。 找到它們的創建位置后,可以嘗試在此時添加一些鎖定。 但是,您的問題仍然可能不是由多個線程破壞內存引起的。 您應該進行調查,直到確信該問題是由於多個線程或其他原因引起的。

我懷疑問題可能與一個或多個COM +組件有關,或者代碼正在調用一些長時間運行的數據庫存儲過程。 無論如何,我懷疑Thread.sleep起作用的原因是因為它給了可疑組件足夠的時間來完成其操作,然后再開始下一個操作。

如果這個理論是正確的,則表明操作之間存在某種相互作用,並且當Thread.Sleep被賦予足夠大的值以允許操作完成時-沒有相互作用問題。 這也表明,COM +組件之一可能正在異步執行某些操作。 解決方案可能是在COM +組件代碼中使用鎖或關鍵部分。 另一個想法是重新設計導致問題的代碼部分,以允許同時進行多個操作。

因此,您遇到的問題可能不是由於您正在查看的C#代碼中有多個線程-可能是由於長時間運行的操作有時會失敗,如果在啟動下一個操作之前沒有足夠的時間完成操作,則有時會失敗。 這可能是也可能不是由於C#代碼中的多個線程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM