2013-02-27 5 views
0

Этот код проверяет 2 клиента, подключенных к сокету, для которого один нажимает кнопку сначала, соединение и прием работают нормально, но если я нажму кнопку клиента, которая является второй в словаре deelnemersTimer и клиентов, Не делай ничего, он просто будет ждать, пока я не нажму первый в словаре. Я почти уверен, что это ожидание в foreach, это неправильно, но что мне нужно изменить, чтобы заставить это работать правильно?foreach with await method

клиентов - это словарь с именами клиентов и их сокетом. deelnemersTimers - это словарь с именами клиентов и временем, когда они нажали кнопку. Также deelnemer является голландским участником.

foreach (Deelnemer deelnemer in deelnemers) 
{ 
    deelnemersTimer[deelnemer.DeelnemerVoornaam + " " + deelnemer.DeelnemerNaam] = await CheckButtons(clients[deelnemer.DeelnemerVoornaam + " " + deelnemer.DeelnemerNaam]); 
} 
deelnemersTimer.Values.Min(); 
var eerste = deelnemersTimer.Where(p => p.Value == deelnemersTimer.Values.Min()).Select(p => p.Key).FirstOrDefault(); 
private async Task<long> CheckButtons(StreamSocket socket) 
{ 
    DataReader reader = new DataReader(socket.InputStream); 

    var actualStringLength = await reader.LoadAsync(1); 
    long time = stopwatch.ElapsedMilliseconds; 

    return time; 
} 
+0

Не могли бы вы подробно описать, что должен делать код? Должен ли результат быть возвращен, как только первый участник нажмет кнопку? Что должно произойти с сокетами других участников? – svick

+0

Когда участники нажимают кнопку, контрольные кнопки возвращают прошедшее время, на этот раз заполняется DeelnemersTimer, и он проверяет, какой из них был первым. Проблема в том, что, когда второй клиент нажимает сначала, foreach все еще ждет первого щелчка, а затем, когда я нажимаю на первый, время по какой-то причине перепутано. – maarten1055

ответ

0

Вы можете сделать это путем создания другой метод, который будет установлен deelnemersTimer и eerste, а затем вызова этого метода без await ции (по крайней мере, не сразу):

private Task ProcessButton(Deelnemer deelnemer) 
{ 
    string id = deelnemer.DeelnemerVoornaam + " " + deelnemer.DeelnemerNaam; 
    deelnemersTimer[id] = await CheckButtons(clients[id]); 

    // is this the first one? 
    if (eerste == null) 
     eerste = id; 
} 

… 

var tasks = deelnemers.Select(ProcessButton); 
await Task.WhenAll(tasks); 

(Это предполагает как deelnemersTimer и eerste являются полями.)

Таким образом, вы начинаете обработку для каждой кнопки одновременно и устанавливаете результаты по мере их завершения.

+0

Weird, 'deelnemersTimer' устанавливается идеально, но когда я нажимаю кнопку на первом клиенте и выходит из' ProcessButton', я получаю «KeyNotFoundException». – maarten1055

+0

@ maarten1055 Где именно вы получаете это исключение? Я ничего не вижу в своем коде, который мог бы это сделать (при условии, что 'clients' настроен правильно), поэтому может произойти что-то еще. – svick

+0

Когда «ProcessButton» выполнен, и он возвращается к 'wait Task.WhenAll (tasks)'. – maarten1055

0

код делает именно то, что вы сказали это сделать: для каждого соединения (асинхронно) ждать нажатия кнопки на этой связи.

Если вы хотите слушать кнопки мыши на все соединений одновременно, вы можете сделать что-то вроде этого:

var buttonTasks = deelnemers.Select(deelnemer => CheckButtons(clients[deelnemer.DeelnemerVoornaam + " " + deelnemer.DeelnemerNaam])); 
var buttonsClicked = await Task.WhenAll(buttonTasks); 
+0

Как это что-то меняет? Исходный код был закончен только после нажатия всех кнопок, и ваш код ведет себя одинаково. Хотя мне не совсем понятно, что именно должен делать код. – svick

+0

Он запускает все «CheckButtons» одновременно, поэтому каждый вызов метода может выполняться индивидуально. Разница в том, что значения секундомера будут правильными. Это моя догадка о том, что должен был делать код. :) –