Is this the proper way to inform the main thread of an event from a Background thread?












0












$begingroup$


The background-thread is an UDP listener. As soon as a certain type of message is received, the main thread has some work to do. My current solution works. But I'm in doubt of the implementation.



My question:




  • Is this a proper way to handle these "simple" situations?

  • Is there another simple and elegant solution that's more commonly accepted?


The server class:



class UdpServer
{
UdpClient listener;
Messenger messenger;

public UdpServer(Messenger messenger)
{
this.messenger= messenger;
}

public void StartListening()
{
listener = new UdpClient(settings.Port);
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, 15000);

try
{
while(true)
{
byte bytes = listener.Receive(ref groupEP);

messenger.Message = string.Format("{0} : {1}",
groupEP.ToString(),
Encoding.ASCII.GetString(bytes, 0, bytes.Length));
}
}
catch(SocketException e)
{
messenger.Message = string.Format("UDP server error: {0}", e.Message);
}
finally
{
listener.Close();
}
}
}


Thread "safety" is sort of implemented in the way that the thread reading the message will only check the value when the Event has been triggered. The event will only be triggered when the value is completely written. As long as each thread gets its own messenger instance, no trouble with threads sharing variables will arise, right?



The messenger class:



//this class is used to transport messages from the receiving threads to the main UI thread.
//subscribe to statusmessageevent in order to receive the messages

class Messenger
{
private string message;
public string Message
{
set
{
message = value;
StatusMessageEventHandler(message);
}
}

public event EventHandler<string> StatusMessageEvent;
private void StatusMessageEventHandler(string message)
{
StatusMessageEvent?.Invoke(this, message);
}
}


The main thread:



static void Main(string args)
{

var UdpMessenger = new Messenger();

UdpMessenger.StatusMessageEvent += MessengerEvent;

var UdpServer = new UdpServer(UdpMessenger);

Task.Factory.StartNew(() => UdpServer.StartListening());

Console.ReadKey();
}


private static void MessengerEvent(object sender, string e)
{
Console.WriteLine(string.Format("Received Message: {0}", e));
}









share|improve this question









New contributor




Micha is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$












  • $begingroup$
    Welcome to Code Review; your code doesn't ever inform 'the main thread' of anything. There is no UI thread, and nothing is trying to call onto it (calling Invoke on an event does not change thread). I'm not sure if this question is on-topic because it sounds like the code doesn't act as expected, and though it looks OK by itself, the context is pretty thin.
    $endgroup$
    – VisualMelon
    10 hours ago










  • $begingroup$
    I cleaned the code somewhat to strip the "point" of unnecessary information. The code works. Perhaps I deleted a bit too much of the original code. But a quick look doesn't seem like I did.... Perhaps my primary question wasn't clear enough. I'm worried about events being lost from other threads. What is the proper way to raise an event cross-thread ?
    $endgroup$
    – Micha
    6 hours ago


















0












$begingroup$


The background-thread is an UDP listener. As soon as a certain type of message is received, the main thread has some work to do. My current solution works. But I'm in doubt of the implementation.



My question:




  • Is this a proper way to handle these "simple" situations?

  • Is there another simple and elegant solution that's more commonly accepted?


The server class:



class UdpServer
{
UdpClient listener;
Messenger messenger;

public UdpServer(Messenger messenger)
{
this.messenger= messenger;
}

public void StartListening()
{
listener = new UdpClient(settings.Port);
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, 15000);

try
{
while(true)
{
byte bytes = listener.Receive(ref groupEP);

messenger.Message = string.Format("{0} : {1}",
groupEP.ToString(),
Encoding.ASCII.GetString(bytes, 0, bytes.Length));
}
}
catch(SocketException e)
{
messenger.Message = string.Format("UDP server error: {0}", e.Message);
}
finally
{
listener.Close();
}
}
}


Thread "safety" is sort of implemented in the way that the thread reading the message will only check the value when the Event has been triggered. The event will only be triggered when the value is completely written. As long as each thread gets its own messenger instance, no trouble with threads sharing variables will arise, right?



The messenger class:



//this class is used to transport messages from the receiving threads to the main UI thread.
//subscribe to statusmessageevent in order to receive the messages

class Messenger
{
private string message;
public string Message
{
set
{
message = value;
StatusMessageEventHandler(message);
}
}

public event EventHandler<string> StatusMessageEvent;
private void StatusMessageEventHandler(string message)
{
StatusMessageEvent?.Invoke(this, message);
}
}


The main thread:



static void Main(string args)
{

var UdpMessenger = new Messenger();

UdpMessenger.StatusMessageEvent += MessengerEvent;

var UdpServer = new UdpServer(UdpMessenger);

Task.Factory.StartNew(() => UdpServer.StartListening());

Console.ReadKey();
}


private static void MessengerEvent(object sender, string e)
{
Console.WriteLine(string.Format("Received Message: {0}", e));
}









share|improve this question









New contributor




Micha is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$












  • $begingroup$
    Welcome to Code Review; your code doesn't ever inform 'the main thread' of anything. There is no UI thread, and nothing is trying to call onto it (calling Invoke on an event does not change thread). I'm not sure if this question is on-topic because it sounds like the code doesn't act as expected, and though it looks OK by itself, the context is pretty thin.
    $endgroup$
    – VisualMelon
    10 hours ago










  • $begingroup$
    I cleaned the code somewhat to strip the "point" of unnecessary information. The code works. Perhaps I deleted a bit too much of the original code. But a quick look doesn't seem like I did.... Perhaps my primary question wasn't clear enough. I'm worried about events being lost from other threads. What is the proper way to raise an event cross-thread ?
    $endgroup$
    – Micha
    6 hours ago
















0












0








0





$begingroup$


The background-thread is an UDP listener. As soon as a certain type of message is received, the main thread has some work to do. My current solution works. But I'm in doubt of the implementation.



My question:




  • Is this a proper way to handle these "simple" situations?

  • Is there another simple and elegant solution that's more commonly accepted?


The server class:



class UdpServer
{
UdpClient listener;
Messenger messenger;

public UdpServer(Messenger messenger)
{
this.messenger= messenger;
}

public void StartListening()
{
listener = new UdpClient(settings.Port);
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, 15000);

try
{
while(true)
{
byte bytes = listener.Receive(ref groupEP);

messenger.Message = string.Format("{0} : {1}",
groupEP.ToString(),
Encoding.ASCII.GetString(bytes, 0, bytes.Length));
}
}
catch(SocketException e)
{
messenger.Message = string.Format("UDP server error: {0}", e.Message);
}
finally
{
listener.Close();
}
}
}


Thread "safety" is sort of implemented in the way that the thread reading the message will only check the value when the Event has been triggered. The event will only be triggered when the value is completely written. As long as each thread gets its own messenger instance, no trouble with threads sharing variables will arise, right?



The messenger class:



//this class is used to transport messages from the receiving threads to the main UI thread.
//subscribe to statusmessageevent in order to receive the messages

class Messenger
{
private string message;
public string Message
{
set
{
message = value;
StatusMessageEventHandler(message);
}
}

public event EventHandler<string> StatusMessageEvent;
private void StatusMessageEventHandler(string message)
{
StatusMessageEvent?.Invoke(this, message);
}
}


The main thread:



static void Main(string args)
{

var UdpMessenger = new Messenger();

UdpMessenger.StatusMessageEvent += MessengerEvent;

var UdpServer = new UdpServer(UdpMessenger);

Task.Factory.StartNew(() => UdpServer.StartListening());

Console.ReadKey();
}


private static void MessengerEvent(object sender, string e)
{
Console.WriteLine(string.Format("Received Message: {0}", e));
}









share|improve this question









New contributor




Micha is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.







$endgroup$




The background-thread is an UDP listener. As soon as a certain type of message is received, the main thread has some work to do. My current solution works. But I'm in doubt of the implementation.



My question:




  • Is this a proper way to handle these "simple" situations?

  • Is there another simple and elegant solution that's more commonly accepted?


The server class:



class UdpServer
{
UdpClient listener;
Messenger messenger;

public UdpServer(Messenger messenger)
{
this.messenger= messenger;
}

public void StartListening()
{
listener = new UdpClient(settings.Port);
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, 15000);

try
{
while(true)
{
byte bytes = listener.Receive(ref groupEP);

messenger.Message = string.Format("{0} : {1}",
groupEP.ToString(),
Encoding.ASCII.GetString(bytes, 0, bytes.Length));
}
}
catch(SocketException e)
{
messenger.Message = string.Format("UDP server error: {0}", e.Message);
}
finally
{
listener.Close();
}
}
}


Thread "safety" is sort of implemented in the way that the thread reading the message will only check the value when the Event has been triggered. The event will only be triggered when the value is completely written. As long as each thread gets its own messenger instance, no trouble with threads sharing variables will arise, right?



The messenger class:



//this class is used to transport messages from the receiving threads to the main UI thread.
//subscribe to statusmessageevent in order to receive the messages

class Messenger
{
private string message;
public string Message
{
set
{
message = value;
StatusMessageEventHandler(message);
}
}

public event EventHandler<string> StatusMessageEvent;
private void StatusMessageEventHandler(string message)
{
StatusMessageEvent?.Invoke(this, message);
}
}


The main thread:



static void Main(string args)
{

var UdpMessenger = new Messenger();

UdpMessenger.StatusMessageEvent += MessengerEvent;

var UdpServer = new UdpServer(UdpMessenger);

Task.Factory.StartNew(() => UdpServer.StartListening());

Console.ReadKey();
}


private static void MessengerEvent(object sender, string e)
{
Console.WriteLine(string.Format("Received Message: {0}", e));
}






c# multithreading






share|improve this question









New contributor




Micha is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











share|improve this question









New contributor




Micha is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









share|improve this question




share|improve this question








edited 11 hours ago









Vogel612

21.9k447131




21.9k447131






New contributor




Micha is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.









asked 13 hours ago









MichaMicha

42




42




New contributor




Micha is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.





New contributor





Micha is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.






Micha is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.












  • $begingroup$
    Welcome to Code Review; your code doesn't ever inform 'the main thread' of anything. There is no UI thread, and nothing is trying to call onto it (calling Invoke on an event does not change thread). I'm not sure if this question is on-topic because it sounds like the code doesn't act as expected, and though it looks OK by itself, the context is pretty thin.
    $endgroup$
    – VisualMelon
    10 hours ago










  • $begingroup$
    I cleaned the code somewhat to strip the "point" of unnecessary information. The code works. Perhaps I deleted a bit too much of the original code. But a quick look doesn't seem like I did.... Perhaps my primary question wasn't clear enough. I'm worried about events being lost from other threads. What is the proper way to raise an event cross-thread ?
    $endgroup$
    – Micha
    6 hours ago




















  • $begingroup$
    Welcome to Code Review; your code doesn't ever inform 'the main thread' of anything. There is no UI thread, and nothing is trying to call onto it (calling Invoke on an event does not change thread). I'm not sure if this question is on-topic because it sounds like the code doesn't act as expected, and though it looks OK by itself, the context is pretty thin.
    $endgroup$
    – VisualMelon
    10 hours ago










  • $begingroup$
    I cleaned the code somewhat to strip the "point" of unnecessary information. The code works. Perhaps I deleted a bit too much of the original code. But a quick look doesn't seem like I did.... Perhaps my primary question wasn't clear enough. I'm worried about events being lost from other threads. What is the proper way to raise an event cross-thread ?
    $endgroup$
    – Micha
    6 hours ago


















$begingroup$
Welcome to Code Review; your code doesn't ever inform 'the main thread' of anything. There is no UI thread, and nothing is trying to call onto it (calling Invoke on an event does not change thread). I'm not sure if this question is on-topic because it sounds like the code doesn't act as expected, and though it looks OK by itself, the context is pretty thin.
$endgroup$
– VisualMelon
10 hours ago




$begingroup$
Welcome to Code Review; your code doesn't ever inform 'the main thread' of anything. There is no UI thread, and nothing is trying to call onto it (calling Invoke on an event does not change thread). I'm not sure if this question is on-topic because it sounds like the code doesn't act as expected, and though it looks OK by itself, the context is pretty thin.
$endgroup$
– VisualMelon
10 hours ago












$begingroup$
I cleaned the code somewhat to strip the "point" of unnecessary information. The code works. Perhaps I deleted a bit too much of the original code. But a quick look doesn't seem like I did.... Perhaps my primary question wasn't clear enough. I'm worried about events being lost from other threads. What is the proper way to raise an event cross-thread ?
$endgroup$
– Micha
6 hours ago






$begingroup$
I cleaned the code somewhat to strip the "point" of unnecessary information. The code works. Perhaps I deleted a bit too much of the original code. But a quick look doesn't seem like I did.... Perhaps my primary question wasn't clear enough. I'm worried about events being lost from other threads. What is the proper way to raise an event cross-thread ?
$endgroup$
– Micha
6 hours ago












0






active

oldest

votes











Your Answer





StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");

StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});






Micha is a new contributor. Be nice, and check out our Code of Conduct.










draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f215935%2fis-this-the-proper-way-to-inform-the-main-thread-of-an-event-from-a-background-t%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























0






active

oldest

votes








0






active

oldest

votes









active

oldest

votes






active

oldest

votes








Micha is a new contributor. Be nice, and check out our Code of Conduct.










draft saved

draft discarded


















Micha is a new contributor. Be nice, and check out our Code of Conduct.













Micha is a new contributor. Be nice, and check out our Code of Conduct.












Micha is a new contributor. Be nice, and check out our Code of Conduct.
















Thanks for contributing an answer to Code Review Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


Use MathJax to format equations. MathJax reference.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f215935%2fis-this-the-proper-way-to-inform-the-main-thread-of-an-event-from-a-background-t%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

How to reconfigure Docker Trusted Registry 2.x.x to use CEPH FS mount instead of NFS and other traditional...

is 'sed' thread safe

How to make a Squid Proxy server?