У меня есть аппаратный компонент, который я использую с помощью связи TCP. Класс, управление имеет 3 рабочие места: Trigger устройство, прослушивать входящие сообщения и поднять event
при получении сообщения:Прочитать аргумент аргумента после ожидания
public class Hardware
{
public event Action<string> OnHardwareMessage;
private NetworkStream stream = new NetworkStream();
public Hardware()
{
Task.Factory.StartNew(() => { Listen(); });
}
private void Listen()
{
//listen to TCP port and raise an event when a message is received
byte[] bytes = new byte[1024];
int bytesRead = stream.Read(bytes, 0, bytes.Length);
string response = Encoding.ASCII.GetString(bytes, 0, bytesRead);
if (OnHardwareMessage != null)
OnHardwareMessage(response);
}
public void Trigger()
{
//Trigger the hardware component
//the response usually takes up to 5 seconds to arrive
}
}
Этот класс используется в цикле внутри view-model
:
public class MainViewModel
{
private static EventWaitHandle hardwareWaiter =
new EventWaitHandle(false, EventResetMode.AutoReset);
private Hardware hardware = new Hardware();
//what i'm doing now is holding a field for incoming event results
private string hardwareResult;
public MainViewModel()
{
hardware.OnHardwareMessage += hardware_OnHardwareMessage;
while (true)
{
hardware.Trigger();
if (hardwareWaiter.WaitOne(10000))
{
//is it possible to read the event argument here?
//do something with the event argument
someObservableCollection.Add(hardwareResult);
//clear the value
hardwareResult = string.Empty;
}
else
{
throw new Exception("Hardware did not respond on time");
}
}
}
//event listener for hardware events
private void hardware_OnHardwareMessage(string message)
{
hardwareResult = message;
hardwareWaiter.Set();
}
}
Что я делаю, это запуск устройства и ожидание ответа до 10 секунд. Теперь я занимаюсь областью поля класса, назначаю сообщение, полученное внутри прослушивателя событий, прочитав его внутри цикла и очистив его.
Мой вопрос в том, есть ли встроенный механизм, который мог бы позволить мне прочитать аргумент события непосредственно после того, как был указан сигнал EventWaitHandle
(вне слушателя событий).
Вы уже устанавливаете 'hardwareResult', вы не можете просто ссылаться на это? Если ваш блок 'WaitOne' выполняется перед вашим обработчиком событий, возможно, вы могли бы просто поместить свой код внутри метода« hardware_OnHardwareMessage »вместо внутри блока« WaitOne »? –
@MikeEason вот что я делаю сейчас, но в случае нескольких прослушивателей событий было бы неплохо не обрабатывать все эти поля. и, к сожалению, я не могу поместить свой код внутри обработчика события, так как результат используется и используется некоторыми другими полями – Yoav