2016-02-14 48 views
0

我的C#應用​​程序停止響應很長一段時間,因爲我打斷了調試,它停止了一個函數。如何在特定的時間內等待函數執行

foreach (var item in list) 
{ 
    xmldiff.Compare(item, secondary, output); 
    ... 
} 

我猜這個函數的運行時間很長,或者它掛起。無論如何,我想等待一段時間(例如5秒)來執行這個函數,如果超過這個時間,我會跳過它並轉到循環中的下一個項目。我該怎麼做?我發現了一些類似的問題,但主要是針對進程或異步方法。

+0

請顯示[mcve]。 – Enigmativity

+0

它確實取決於Compare()'方法本身的內部代碼。沒有我們可以插入的神奇代碼,只會暫停/中止任何類似的事情 –

+0

如果您使用的是.net 4.0及以上版本,我建議您查看TPL /異步...等待。對於不應該阻止/掛起UI的長時間運行的進程。您需要將進程推送到後臺線程,最好在線程池中。 – CarbineCoder

回答

2

你可以用殘酷的方法做到這一點:啓動一個線程來完成工作,如果加入失敗,則用超時加入,然後放棄它。

例子:

var worker = new Thread(() => { xmlDiff.Compare(item, secondary, output); }); 
worker.Start(); 
if (!worker.Join(TimeSpan.FromSeconds(1))) 
    worker.Abort(); 

但要注意 - 中止線程不被認爲是好的,可以讓你的應用程序不穩定。如果可能的話嘗試修改Compare以接受CancellationToken取消比較。

+0

爲什麼降票?除了放棄運行的線程之外,還有其他非合作方法可以取消某個方法嗎? – Haukinger

+0

你可以在代碼示例中給它嗎? – Ahmad

+0

當然,沒問題。 – Haukinger

0

我會避免直接使用線程並使用Microsoft的Reactive Extensions(NuGet「Rx-Main」)來抽象出線程的管理。

我不知道xmldiff.Compare(item, secondary, output)確切的簽名,但如果我認爲它會產生一個整數,然後我可以用的Rx做到這一點:

var query = 
    from item in list.ToObservable() 
    from result in 
     Observable 
      .Start(() => xmldiff.Compare(item, secondary, output)) 
      .Timeout(TimeSpan.FromSeconds(5.0), Observable.Return(-1)) 
    select new { item, result }; 

var subscription = 
    query 
     .Subscribe(x => 
     { 
      /* do something with `x.item` and/or `x.result` */ 
     }); 

這通過每個item自動迭代,然後開始xmldiff.Compare背景計算,但只允許每個計算在返回默認值-1之前花費多達5.0秒。

subscription變量是IDisposable,所以如果您想在完成之前中止整個query,請撥打.Dispose()

0

我跳過它,去到下一個項目在環

通過「跳過」,你的意思是「離開那裏」或「取消」?這兩種情況完全不同。但對於這兩個我建議你使用Task。改善

//generate 10 example tasks 
var tasks = Enumerable 
    .Range(0, 10) 
    .Select(n => new Task(() => DoSomething(n))) 
    .ToList(); 

var maxExecutionTime = TimeSpan.FromSeconds(5); 

foreach (var task in tasks) 
{ 
    if (task.Wait(maxExecutionTime)) 
    { 
     //the task is finished in time 
    } 
    else 
    { 
     // the task is over time 
     // just leave it there 
     // the loop continues 
     // if you want to cancel it, see 
     // http://stackoverflow.com/questions/4783865/how-do-i-abort-cancel-tpl-tasks 
    } 
} 

的一件事是「你真的需要運行的任務一個接一個?」如果他們是獨立的,你可以並行運行它們。