2010-11-03 55 views
0

我有一個VB.NET WinForms應用程序使用順序Parallel.For語句。.NET錯誤 - Threading.Timer影響Parallel.For性能

在添加Threading.Timer之後,Parallel.For循環緩慢進行爬網,內核時間量跳至近80%。

這兩者在我的代碼中沒有關係(即,兩者都不是由另一方運行),也不共享任何代碼或數據。

刪除計時器可以解決問題。

有沒有其他人經歷過這種行爲?解決此問題的最佳方法是什麼(如果需要,寧願不創建WinForms計時器)?

這是由定時器執行的代碼:

Public Sub Tick() 
    IO.File.WriteAllText("c:\test.txt", DateTime.Now.ToString()) 
End Sub 

這是計時器創建語句:

tmrFile = New Threading.Timer(AddressOf Tick, Nothing, New TimeSpan(0, 0, 0), New TimeSpan(0, 1, 0)) 
+0

有趣..你可以張貼一些簡單的沒有經過充分測試的代碼重現問題的代碼? – 2010-11-03 20:35:10

+0

在這方面很簡單,可能不是很簡單。平行的fors正在做大量的記憶複製和圖像重採樣。線程計時器只是使用當前日期時間更新文件。如果我有一些時間,我會看看我是否不能重現行爲。 – ColorEyes 2010-11-03 20:49:43

+0

@ColorEyes,如果你刪除了Parallel.For循環,只是計時器東西讓你的機器忙? – 2010-11-03 21:31:13

回答

1

是您的定時信號經常?如果是這樣,你可能會被定時器的線程數量壓倒。可以運行的線程數量是有限的,並且如果Timer頻繁發送信號需要太多時間,那麼其餘的代碼將會受到影響。

你可以分析你的計時器在做什麼並分享這些信息嗎?它發出的信號多麼頻繁,它正在執行的任何特別粗糙的代碼,如果它正在執行並行任務等。

+0

它每分鐘發一次信號。當它發出信號時,將當前日期和時間寫入文件。我試圖增加到10分鐘,但同樣的行爲存在。 – ColorEyes 2010-11-03 22:09:39

+0

它如何寫入文件?鎖定打開,寫入,刷新,關閉操作?只希望在下一個信號的下一個線程之前完成寫入操作?當您使用計時器時代碼開始變慢還是隨着時間變慢? – 2010-11-03 22:12:32

+0

如果您對這些細節感興趣,請在上面張貼代碼。然而,這並不重要,因爲即使代碼被註釋掉了(即空的勾號),該行爲仍然顯示出來。 – ColorEyes 2010-11-03 22:19:48

0

請嘗試將它從線程池中取出!我把一個簡單的計時器課程放在一起給你試用(不是生產代碼,請介意你)。這個類運行在一個單獨的線程中。

類:

public class ThreadedTimer : IDisposable 
    { 
    private readonly AutoResetEvent _isStopping = new AutoResetEvent(false); 
    public ThreadedTimer(Action f, int interval) 
    { 
     Thread t = new Thread(() => 
     { 
      while (!_isStopping.WaitOne(interval)) 
      { 
       f(); 
      } 
     }); 
     t.IsBackground = true; 
     t.Start(); 
    } 

    public void Dispose() 
    { 
     _isStopping.Set(); 
    } 
    } 

啓動一個定時器:

var timer = new ThreadedTimer(() => Debug.WriteLine("Test"), 1000); 

更新: 在VB下面

Imports System.Threading 
Public Class ThreadedTimer 
    Implements IDisposable 
    Private ReadOnly _isStopping As New AutoResetEvent(False) 

    Public Sub New(ByVal f As Action, ByVal interval As Integer) 
     Dim t As New Thread(Sub() 
           While Not _isStopping.WaitOne(interval) 
            f() 
           End While 
          End Sub) 
     t.IsBackground = True 
     t.Start() 
    End Sub 

    Public Overloads Sub Dispose() Implements IDisposable.Dispose 
     _isStopping.[Set]() 
    End Sub 
End Class 
+0

謝謝,但這段代碼是如此微不足道,這樣一個明顯的解決方案,我已經實現了我自己的線程計時器。另外,我的問題並不是圍繞如何實現簡單的解決方案,這就是爲什麼Threading.Timer不能用我的代碼工作?這是我正在努力解決的問題的關鍵。 – ColorEyes 2010-11-03 23:26:39

+0

@ColorEyes對不起,它沒有幫助,但沒有理由成爲一個洞。這種情況違背了本網站的精神。人們應該如何知道你認爲「明顯的解決方案」? – 2011-02-08 21:30:24