我有這樣的代碼創建一個任務:如何暫停執行任務
Task.Factory.StartNew(() =>
{
ExtractStuff(fileName);
});
有時候,我需要暫停幾秒鐘內ExtractStuff
是否確定使用常規的Thread.Sleep(1000)
?還是有另一種方法來暫停正在運行的任務?
我有這樣的代碼創建一個任務:如何暫停執行任務
Task.Factory.StartNew(() =>
{
ExtractStuff(fileName);
});
有時候,我需要暫停幾秒鐘內ExtractStuff
是否確定使用常規的Thread.Sleep(1000)
?還是有另一種方法來暫停正在運行的任務?
我相信這樣做很好,但最好使用TaskCreationOptions.LongRunning。
Task.Factory.StartNew(() =>
{
ExtractStuff(fileName);
},TaskCreationOptions.LongRunning);
我不明白這是如何涉及到這個問題? –
@James,這提示任務調度程序您的任務可能需要一段時間才能執行,因此它應該避免在Task中綁定一個有限的資源(如線程池)。這可能會產生一些額外開銷(從分配新線程而不是使用池中的線程),但可能會阻止其他問題(多任務佔用池並及時休眠,阻止其他任務啓動)。你打算在你的任務中睡覺,你可能應該考慮自己長時間運行。 –
如果需要推遲ExtractStuff的執行,你可以在ThreadPool.RegisterWaitForSingleObject看看,與從未設置WaitHandle的結合。
private static WaitHandle NeverSet = new WaitHandle();
private void ExtractStuff(object state)
{
string filename = state as string;
....
}
private void StartExtract(string filename);
{
ThreadPool.RegisterWaitForSingleObject(NeverSet, ExtractStuff, fileName, seconds * 1000, true);
}
希望這會幫助你在你的追求。
不,我不需要延遲ExtractStuff的執行。我需要根據內部邏輯在中間暫停執行ExtractStuff。 – user1615362
Thread.Sleep會阻塞運行任務的線程(這並不理想),但只要沒有運行大量數據,它可以是一個可以接受的折衷方案(低風險,性能不是很大的問題)並行的任務。 .NET 4.5對'async/await'和Task.Delay有一些改進,它會隱式設置基於計時器的延續(不需要阻塞正在運行的線程),但這在4.0中不是直接可用的。
你可以自己做同樣的事情,像這樣的東西(沒有測試很多,所以請謹慎使用):
class Program
{
static void Main(string[] args)
{
var fullAction = RunActionsWithDelay(DoSomething, 2000, DoSomethingElse);
fullAction.Wait();
Console.WriteLine("Done");
Console.ReadLine();
}
static Task RunActionsWithDelay(Action first, int delay, Action second)
{
var delayedCompletion = new TaskCompletionSource<object>();
var task = Task.Factory.StartNew(DoSomething);
task.ContinueWith(t =>
{
if (t.IsFaulted)
{
delayedCompletion.SetException(t.Exception);
}
else
{
Timer timer = null;
timer = new Timer(s =>
{
try
{
DoSomethingElse();
delayedCompletion.SetResult(null);
}
catch (Exception ex)
{
delayedCompletion.SetException(ex);
}
finally
{
timer.Dispose();
}
}, null, delay, Timeout.Infinite);
}
});
return delayedCompletion.Task;
}
static void DoSomething()
{
Console.WriteLine("Something");
}
static void DoSomethingElse()
{
Console.WriteLine("Something Else");
}
}
這是相當難看,但你可以封裝比它上面好一點。它確實消除了「懸掛」線程,但是與設置延續相關的額外性能開銷。如果你有很多並行任務正在運行,並且他們都需要引入延遲,我真的只是建議你這樣做。
你說Thread.Sleep會阻塞運行任務的線程,但是如果我使用LongRunning,是不是會導致只有任務被暫停而不是運行任務的線程? – user1615362
+1,並感謝擴大我的答案,應該回到它。 –
@ user1615362'Thread.Sleep()'總是阻塞當前線程。如果你使用'LongRunning',它不會是'ThreadPool'中的一個線程,但它仍然是一些線程,所以它仍然是浪費。 – svick
您可以使用Task.Delay(超時)並等待您的ExtractStuff方法。
private async string ExtractStuff(fileName)
{
// Your Code
await Task.Delay(timeout);
}
當你說,是否可以使用Thread.Sleep(),你是什麼意思? –
某些其他線程是否需要暫停某些工作? –
我的意思是它會暫停任務,或者它會暫停父線程。 – user1615362