在竞争状态下使用线程读取UDP端口上的数据 [英] read data on UDP port using thread in race condition
本文介绍了在竞争状态下使用线程读取UDP端口上的数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在读取一个UDP客户端端口上以字节为单位的数据,该端口由另一台服务器广播.
我创建了一个带有睡眠时间的单线程,当数据传入速度很慢时它可以工作,但是当数据传入增加时,它的内存使用量就会增加,并以未知错误终止.
我希望在这样的线程上获得帮助,例如,在完成一项工作后再转到下一项工作时,线程应该以这种方式进行管理,这不仅取决于睡眠时间,还可以使我的线程顺利运行.
谢谢.
I am reading data in bytes on one UDP client port which is broadcast by other server.
I have created a single thread with sleep time it works when data incoming is slow but when data incoming incresaes then its memory use go high and terminate with unknown error.
I want help on this like thread should manage in such a manner after completion of one job come to next job not only depend on sleep time, so my threading could run smoothly.
Thanks.
public partial class FormUDP : Form
{
UdpClient listener = new UdpClient(9871);
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, 0);
bool ProcessStatus; //process
Thread _UDPthread; //Thread
private void btn_rcve_Click(object sender, EventArgs e)
{
ThreadStart _process = new ThreadStart(receivemessages);
_UDPthread = new Thread(_process);
ProcessStatus = true;
_UDPthread.Start();
}
private void receivemessages()
{
MessageBox.Show("start");
while (ProcessStatus)
{
try
{
if (listener.Available > 0)
{
byte[] buffer = listener.Receive(ref groupEP);
///**Start convert **//
TBCastMessageHeader bcastHeader = new TBCastMessageHeader();
IntPtr bcastHeaderPtr;
bcastHeaderPtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(TBCastMessageHeader)));
Marshal.Copy(buffer, 0, bcastHeaderPtr, buffer.Length);
bcastHeader = (TBCastMessageHeader)(Marshal.PtrToStructure(bcastHeaderPtr, typeof(TBCastMessageHeader)));
try
{
switch (bcastHeader.MessageCode)
{
case 10:
// convert byte to structure and insert into sql database
break;
}
}
catch (Exception ex)
{ }
finally { Marshal.FreeHGlobal(bcastHeaderPtr); C.Collect();}
if (ProcessStatus)
{
Thread.Sleep(new TimeSpan(0, 0, 0, 0, 5)); // 5 miliseconds
}
}
// Structure defined
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 0x1)]
public struct TBCastMessageHeader
{
public ushort MessageCode;
public uint TimeStamp;
public ushort MessageLength;
public sbyte NumberOfDecimals;
public ushort Reserved;
}
}
推荐答案
使用睡眠时间毫无意义.对于您的情况,您应该从一开始就创建一个线程(不要单击),并使用线程同步原语(例如,System.Threading.EventWaitHandle
)使它保持休眠状态(实际上,在唤醒状态下,不使用任何CPU时间).更高级的用法是使用通用阻塞队列,每个元素代表一个线程的任务",请参阅我的技巧/窍门文章: ^ ].
创建线程的最佳方法是使用包装器,方法如下: ^ ].
有关一般设计方案,请参阅我对类似问题的回答:
Control.Invoke()与Control.BeginInvoke() [ ^ ]
Treeview Scanner和MD5的问题 [来自同一端口号的多个客户端 [如何获取keydown事件在vb.net中的不同线程上操作 [
Using sleep time is pointless. In your case, you should create a thread from the very beginning (not by click) and keep it sleeping (actually, in wait state not using any CPU time until awaken) using thread synchronization primitives, likeSystem.Threading.EventWaitHandle
. More advanced use would be using a generic blocking queue with elements each representing a "task" for a thread, see my Tips/Trick article: Simple Blocking Queue for Thread Communication and Inter-thread Invocation[^].
Best way to create a thread is using wrapper, here is how: How to pass ref parameter to the thread[^].
For a general design schema, see my Answers to similar Questions:
Control.Invoke() vs. Control.BeginInvoke()[^]
Problem with Treeview Scanner And MD5[^]
Multple clients from same port Number[^] (this one is for TCP, but many recommendations are still valid for your case)
How to get a keydown event to operate on a different thread in vb.net[^]
—SA
这篇关于在竞争状态下使用线程读取UDP端口上的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文