2012-09-18 59 views
4

我有一個Timer和Im在一段時間內調用一些函數。現在我有這樣的事情:在間隔異步中並行運行一些函數?

private System.Timers.Timer timer; 
private int sync; 

void Start() 
{ 
    timer = new System.Timers.Timer(interval); 
    timer.Elapsed += new ElapsedEventHandler(Elapsed); 
    timer.Enabled = true; 
} 

void Elapsed(object s, ElapsedEventArgs e) 
{ 
    if (System.Threading.Interlocked.CompareExchange(ref sync, 1, 0) == 0) 
    { 
    Parallel.Invoke(() => Function1(),() => Function2(),() => Function3(), 
        () => Function4()); 
    } 
    sync = 0; 
} 

這並不壞。我可以並行啓動函數,一個函數不能運行2+次,只有一次(這是我想要的)。問題是:可以說function4()需要更長的時間,然後我的interval,所以其他功能也必須等待。如果我在那裏刪除sync,其他函數不會等待,但另一個function4()調用可能在另一個線程中啓動 - 而且我不希望這兩個函數運行兩次。有什麼建議麼?謝謝

回答

3

您必須單獨跟蹤每個功能,以便您可以控制立即可以啓動哪些功能以及需要等待的功能,例如,

private AutoResetEvent f1 = new AutoResetEvent(true); 
private AutoResetEvent f2 = new AutoResetEvent(true); 
... 

void Elapsed(object s, ElapsedEventArgs e) 
{ 
    ... 
    Parallel.Invoke(() => { f1.WaitOne(); Function1(); f1.Set(); }, 
        () => { f2.WaitOne(); Function2(); f2.Set(); } 
        ... 
    ... 
} 

像這樣的東西會阻止任何正在執行的功能,並允許其他的功能啓動哪些不是。

+0

謝謝。不知道我100%明白這一點:)但我會盡力實施這一個。 – silla

+1

@silla任何時候只能調用一次'FunctionX',但不應該阻止其他調用。所以基本上會發生什麼是你爲所有4個函數啓動一個並行調用,如果它已經通過'WaitOne'運行,我們阻止'FunctionX'的執行。一旦'FunctionX'在另一個線程中完成,它會調用'Set',然後釋放該塊並允許另一個線程執行'FunctionX'。 – James

+0

林困惑,但你確定我必須使用新的AutoResetEvent(false);而不是新的AutoResetEvent(true);?因爲如果我使用false,則沒有任何函數正在運行,但是它們是真實的。 – silla

相關問題