2014-02-10 2 views
3

Мне было интересно, какой лучший способ подделать долговременную задачу, когда параллельно выполняются несколько задач. Первое, что приходит на ум, это Thread.SleepКаков наилучший способ подделать длительный процесс параллельной обработки?

public void FakeLongRunningTask() 
{ 
Thread.Sleep(5000); 
} 

Однако проблема с выше код, что вызов Thread.Sleep будет блокировать этот поток, который означает, что он сдастся это время процессор срез, поэтому при вызове метода с Thread. Сон в параллельной среде так же хорош, как вообще не звонить. Поэтому, если я запускаю три задачи параллельно, и один из них вызывает Thread.Sleep, эта задача не будет влиять на производительность (хотя это может заставить CLR генерировать больше потоков !!!). Но я хочу подделать задачу, которая повлияет на общую производительность.

ответ

5

Если вы хотите активное ожидание, которое будет держать одно ядро ​​процессора занят, вы могли бы попробовать что-то вроде этого:

public void BusyWait(int milliseconds) 
{ 
    var sw = Stopwatch.StartNew(); 

    while (sw.ElapsedMilliseconds < milliseconds) 
     Thread.SpinWait(1000); 
} 
9

Используя 4.5 рамки, я думаю, что вы можете использовать Task.Delay

EDIT: В ответ на запрос. Вот непроверенный образец:

async Task LongRunningOperation() 
{ 
    await Task.Delay(5000); 
} 

private async void SomeEvent(object sender, EventArgs e) 
{ 
    await LongRunningOperation(); 
} 

второго EDIT: Использование механизма 4.0, это может работать (непроверенный):

Task Delay(int interval) 
{ 
    var z = new TaskCompletionSource<object>(); 
    new Timer(_ => z.SetResult(null)).Change(interval, -1); 
    return z.Task; 
} 
+0

+1 «Задержка» идеальна, поскольку OP не хочет фактически блокировать поток. Этот ответ был бы более полным, если бы вы предоставили короткий, но полный пример. – James

+1

Не уверен в этом. 'Task.Delay' тоже не использует CPU, не так ли? –

+0

@MatthewWatson да ваше право, оно не используется. – terrybozzio

0

вы почти сделали это:

public async Task FakeLongRunningTask() 
{ 
    await Task.StartNew(() => Thread.Sleep(5000)); 
} 

и использование в каком-то событии (извините, Big Daddy = D):

private async void SomeEvent(object sender, EventArgs e) 
{ 
    await FakeLongRunningTask(); 
} 

Обратите внимание, что вы должны использовать его с await (который требуется метод абонента будет помеченный async).

Смежные вопросы