2015-09-21 2 views
2

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

Эффективно класс настроен так:

void Loop() 
{ 
    for (int i = 0; i < 100; i++) 
    { 
     //need to block calls to this until UpdateComplete is hit 
     Update(i); 
    } 
} 

void Update(int i) 
{ 
    //asynchronous - returns immediately 
} 

void UpdateComplete()//called from another thread 
{ 
    //unblock further calls to Update(); 
} 

большой нюанс в том, что это не представляется возможным назвать Update() до того UpdateComplete() имеет «вернулся» или был calledback.

Игнорирование любых побочных эффектов UI, есть ли четкое решение этой проблемы?

Я в настоящее время есть две стратегии - один Hacky и один я чувствую себя слишком сложно:

1 - Hacky: Установить глобальный класс булево IsBlocked, что Update() наборы для true и UpdateComplete() наборы к ложным, и внутри моей петли (в Loop()), просто введите while (IsBlocked){}.

2 - Сложный: полностью избавиться от петли. Звоните Update(0); изнутри Loop() вместо этого и получите UpdateComplete() позвоните по телефону Update(1);, Update(2); и так далее.

Я думаю, я надеюсь, что-то вроде Thread.Pause, которые затем могут быть удаленно «возобновился» другим потоком (отдельный один, который вызывает UpdateComplete() Любые идеи оценили!

+1

Я хотел бы использовать 'асинхронных/await' – Eser

+0

Поместите код, где она принадлежит. Добавьте еще один аргумент в Update(), bool с именем «executeAferronously». –

+1

Оба способа, которые вы описываете, не имеют преимуществ при нарезке резьбы. Они эффективно работают на одном потоке во все времена, они просто переходят из одного потока в другой. Так что это только усложняет ситуацию. –

ответ

2

Асинхронные/ждем также может быть использованы здесь

TaskCompletionSource<object> tcs = null; 

async void Loop() 
{ 
    for (int i = 0; i < 100; i++) 
    { 
     tcs = new TaskCompletionSource<object>(); 
     Update(i); 
     await tcs.Task; 
    } 
} 

void Update(int i) 
{ 
    //asynchronous - returns immediately 
} 

void UpdateComplete()//called from another thread 
{ 
    tcs.TrySetResult(null); 
    //unblock further calls to Update(); 
} 
+0

Это круто - я принимаю его 'tcs.TrySetResult (null);' будет работать при вызове из другого потока? – maxp

+0

@maxp Да, BTW: если у вас есть данные в 'UpdateComplete', чтобы вернуться к методу Loop, вы можете передать его' TrySetResult'. Тогда ваш код ожидания будет «var some data = wait tcs.Task» – Eser

0

сообщение обновления в пул потоков, используя QueueUserWorkItem

есть счетчик количества отправленных элементов.

есть основной поток ждать на AutoResetEvent

Когда EAC h завершение обновления уменьшает счетчик под блокировкой.

Когда количество хитов 0 Установите AutoResetEvent будить главный поток

Я не отправлял никакого кода, потому что я предположил, что вы можете Google, как сделать каждый бит, если не комментировать, и я могу добавить код

+0

Интересно, я посмотрю, что (btw not my downvote) – maxp

+0

@maxp, если этот подход звучит разумно для вас, вы должны обновить свой вопрос - в настоящее время это звучит так, что все элементы * должны обрабатываться последовательно (в то время как это сообщение предлагает параллельное выполнение). - это несоответствие может быть причиной (не моего) нисходящего потока, а также предотвращает его возмещение. –

+0

@AlexeiLevenkov Да, вы правы, они должны быть последовательными. – maxp

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