2016-06-30 2 views
-2

У меня есть следующий код:Task.Wait на другой поток C#

//requests bar data 
Task.Run(() => CONNECTION.ReqBarData()).Wait(); 

//the bars arrive on different thread here 
virtual override void OnBar() 
{ 
//takes a while till all bars arrive 
} 

Проблема заключается в том, что мне нужно ждать на все бары, чтобы прибыть в методе OnBar() и мой код выше только ожидание вызов ReqBarData(). Другими словами ReqBarData() занимает всего несколько миллисекунд, но метод OnBar() занимает 30 и более секунд. Я также хочу, чтобы мой интерфейс был отзывчивым, пока я жду, когда OnBar() закончит. спасибо

+0

Пожалуйста, предоставьте детали о том, как первая строка коды и функция OnBar связаны Не совсем ясно, как две функции связаны друг с другом. Похоже, что это [Асинхронный шаблон на основе событий] (https://msdn.microsoft.com/en-us/library/ms228969 (v = vs.110) .aspx). Если да, взгляните на [эту страницу MSDN] (https://msdn.microsoft.com/en-us/library/hh873178 (v = vs.110) .aspx # Anchor_1) –

+0

Если у вас есть длинный метод в 'OnBar', и вы получаете это в потоке пользовательского интерфейса каким-то образом (через invoke?), тогда вы можете использовать тот же' Task.Run' для асинхронного запуска этого кода. Вы этого не делаете, потому что у вас есть проблемы. Расскажи нам. – Sinatr

+0

Вы никогда не должны называть 'Wait()'; вы пытались использовать 'await' вместо этого? –

ответ

0

Я иду на предположении, что OnBar не Actaully принимать 30 секунд для запуска, что он делает, это занимает 30 секунд до Старт после вызова ReqBarData. Если это так, то у вас действительно есть Event-based Asynchronous Pattern, самый простой способ справиться с тем, что вы хотите сделать, - это преобразовать его в Task-based Asynchronous Pattern.

Поскольку вы не предоставили Minimal, Complete, and Verifiable example, мне нужно будет внести некоторые изменения в то, как я думаю, что ваша программа работает. Вам нужно будет обновить свой вопрос надлежащим примером, если вы хотите, чтобы код был ближе к тому, что у вас действительно есть. Я сделал предположение, что ReqBarData имеет перегрузку, которая принимает параметр object state, который будет передан в OnBar, а OnBar также получает список объектов, которые он ожидал.

public Task<List<Bar>> RequestDataAsync() 
{ 
    var tcs = new TaskCompletionSource<List<Bar>>(); 
    //This does not need to be on a separate thread, it finishes fast. 
    CONNECTION.ReqBarData(tcs); 
    return tcs.Task; 
} 

virtual override void OnBar(List<Bar> someBars, object stateInfo) 
{ 
    //We get our TaskCompletionSource object back from the state paramter 
    var tcs = (TaskCompletionSource<List<Bar>>)stateInfo; 

    //we set the result of the task. 
    tcs.SetResult(someBars); 
} 

Чтобы использовать его без блокировки пользовательского интерфейса вы просто вызовите функцию и await она используется асинхронной/ждет

public async void Button1_Click(object sender, EventArgs args) 
{ 
    await LoadData(); 
} 

private async Task LoadData() 
{ 
    List<Bar> bars = await myConnectionClass.RequestDataAsync(); 
    SomeBinding.DataSource = bars; 
} 
+0

спасибо за предоставление кода примера .. ReqBarData (контракт c), где c - это контракт, требующий баров ... OnBar() возвращает строки по одному с назначенным reqID, который я отслеживаю в коде. бары начинают поступать мгновенно, но если запрос рассчитан на большое количество баров, это может занять 10-30 секунд .. и я хочу дождаться, когда все они войдут. плохо попробуйте свой код и посмотрите, могу ли я получить он работал – AlgoAlpha

+0

это было именно то, что мне нужно .. спасибо. – AlgoAlpha

0

Метод OnBar() занимает 30 и более секунд.

Если этот метод вызывается в UI потоке, то вы можете использовать Task.Run, чтобы запустить его в другом потоке (по аналогии с тем, что вы уже делаете, поэтому мои комментарии как это не ясно, если это так).

Изменить

virtual override void OnBar() 
{ 
    ... whatever 
} 

в

virtual override void OnBar() => Task.Run(() => 
{ 
    ... whatever 
}); 

Но более вероятно, что вы должны просто использовать async:

async void SomeEventHandlerToExampleButtonClick(object sender, SomeEventArgs e) 
{ 
    await Task.Run(() => CONNECTION.ReqBarData()); 
    ... // you are here after ReqBarData() is finished and you are not blocking UI so far 
} 
+0

.. спасибо за это .. плохо посмотрим, смогу ли я заставить его работать. – AlgoAlpha

+0

OnBar - это метод обратного вызова, считайте его как где-то еще в коде, в котором OP имеет 'CONNECTION.DataAvailable + = OnBar', OP хочет дождаться завершения работы, это задание для' TaskCompletionSource' –

+0

@ScottChamberlain , * «OnBar - метод обратного вызова» * - как вы знаете? Что касается завершения, я знаю 'async/await' шаблон, подобный этому, для вызова методов« Action <> »и не блокирует пользовательский интерфейс, но я не знаю, что такое' TaskCompletionSource'. Что я должен исправить (где проблема)? Возможно, вы можете отправить другой ответ? – Sinatr

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