Как правильно подписаться к event'у, который вызывается в другом потоке?
У меня работает UDP Socket, который читает информацию с broadcast сервера. Мне нужно, чтобы когда у меня формировалось сообщение от сервера срабатывал event и метод обработки этого event'a начал работать в основном потоке. Вот так у меня это сделано. Поток читает всё что посылает сервер, но когда дело доходит до Invoke, ничего не происходит
Сам класс:
public class UdpLocation
{
public event UdpLocationEventHandler MessageReceived;
public string IPAddress { get; set; }
public int Port { get; set; }
public void Start()
{
Thread thread = new Thread(StartListen)
{ IsBackground = true };
thread.Start();
thread.Join();
StartListen();
}
private void StartListen()
{
if (IPAddress == string.Empty || Port == 0)
throw new Exception("IPAddress or Port is non initilizated");
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
client.Bind(new IPEndPoint(System.Net.IPAddress.Parse(IPAddress), Port));
EndPoint remoteIP = new IPEndPoint(System.Net.IPAddress.Any, 0);
byte[] data = new byte[1024];
StringBuilder builder = new StringBuilder();
while (true)
{
do
{
client.ReceiveFrom(data, ref remoteIP);
builder.Append(Encoding.Unicode.GetString(data));
} while (client.Available > 0);
MessageReceived?.Invoke(this, new UdpLocationEventArgs()
{
Latitude = builder.ToString(),
Longitude = builder.ToString()
});
builder.Clear();
}
}
}
Его использование:
class Proga
{
static void Main()
{
UdpLocation location = new UdpLocation() { IPAddress = "192.168.0.2", Port = 8080 };
location.Start();
location.MessageReceived += (s, e) => Console.WriteLine($"{e.Latitude} {e.Longitude}");
Console.ReadKey();
}
}
Ответы (1 шт):
Автор решения: Никита
→ Ссылка
Вообщем я наконец-таки понял что нужно подписываться на event раньше, чем запустится поток чтения сервера. Ещё я отказался от класса UdpLocationEventArgs и сделал так:
public string Longitude
{
get
{
return _long;
}
set
{
_long = value;
MessageReceived.Invoke(this, new UdpLocationEventArgs() { Longitude = value });
}
}
public string Latitude
{
get
{
return _lat;
}
set
{
_lat = value;
MessageReceived.Invoke(this, new UdpLocationEventArgs() { Latitude = value });
}
}
Ещё немного видоизменил цикл обработки:
private void StartListen()
{
// ...
while (true)
{
do
{
client.ReceiveFrom(data, ref remoteIP);
builder.Append(Encoding.Unicode.GetString(data));
} while (client.Available > 0);
Latitude = builder.ToString();
Longitude = builder.ToString();
builder.Clear();
}
}
Само использование выглядит так:
class Proga
{
static void Main()
{
UdpLocation location = new UdpLocation() { IPAddress = "192.168.0.2", Port = 8080 };
location.MessageReceived += (s, e) => Console.WriteLine($"{e.Latitude} {e.Longitude}");
location.Start();
Console.ReadKey();
}
}