任何人都可以帮忙吗? 谢谢, Dennis Owens 解决方案 Dennis Owens< a ***** **@discussions.microsoft.com>写道:我试图从一个表单运行一个线程,并且每隔一段时间该线程将引发一个事件以供表单读取。当表单获取事件时,表单会将事件放入数据集中,并将其显示在表单上的数据网格中。问题是线程将慢慢占用所有处理器时间。在大约8个事件之后,表格甚至不再响应。这是我的测试代码的内容。 我并不感到惊讶 - 你有一个紧密的循环中的8个线程。这是绑定处理器的b !然而,你还有一些其他的恶作剧 正在进行...... 首先,你在非线程中访问stopRunning-安全的方式。你要应该声明它是不稳定的,或者在 a锁定中包含对它的任何访问权限。 其次,你应该永远不会从非UI线程更新GUI,因为你现在正在做b $ b。您应该使用Control.Invoke在UI线程上调用委托 。 第三,为什么要从事件中调用localThread.Interrupt()? 那个时候,你实际上正在运行*你正在尝试的线程中断! - Jon Skeet - < sk *** @ pobox.com> http://www.pobox.com/~skeet 如果回复小组,请不要给我发邮件 中断只是一个疯狂的猜测,试图阻止它吸收所有的处理器时间。我忘了把它留在那里。该方法中唯一的一行应该是在数据集中添加行。至于你的第二件事,这是导致线程接管的原因。好吧,我会查找Control.Invoke,看看我能搞清楚。我仍然没有看到八个线程,只是形式和测试线程 谢谢Dennis Owen stopRunning不需要声明为volatile而且不应该使用 带锁。 本机整数赋值是原子操作以及原生整数 促销(即便如此,最后也不算数)。 没有编译器会优化远离变量的加载 非常重要的循环体(就像循环内部的非内联方法调用一样)。 你不需要为原子的单个变量释放/获取语义 赋值。 使用LOCK访问它将是不必要的性能打击,如果没有 说错误。 我想他错误地解释了Thread.Interrupt的含义,并且你的其余评论是正确的。 -Valery。 请访问我的博客: http://www.harper.no/valery " Jon Skeet [C#MVP]" < SK *** @ pobox.com>在消息中写道 新闻:MP ************************ @ msnews.microsoft.c om ... Dennis Owens< an ******* @ discussion.microsoft.com>写道:我试图从一个表单运行一个线程,并且每隔一段时间该线程将引发一个事件以供表单读取。当表单获取事件时,表单会将事件放入数据集中,并将其显示在表单上的数据网格中。问题是线程将慢慢占用所有处理器时间。在大约8个事件之后,表格甚至不再响应。以下是我的测试代码的内容。 我并不感到惊讶 - 你有一个紧密循环的8个线程。这是接管处理器的必要条件!但是,你还有一些其他的恶作剧...... 首先,你是以非线程安全的方式访问stopRunning。你应该声明它是易失性的,或者在锁定中包含对它的任何访问权。 其次,你永远不应该从非UI线程更新GUI,正如你现在正在做的那样。您应该使用Control.Invoke来调用UI线程上的委托。 第三,为什么要从事件中调用localThread.Interrupt()?那时,你实际上正在*正在尝试中断的线程中运行* - Jon Skeet - < sk *** @ pobox.com> ; http://www.pobox.com/~skeet 如果回复小组,请不要给我发邮件 I am trying to run a thread off of a form, and every once in a while the thread will raise an event for the form to read. When the form gets the event, the form will place the event into a dataset and display it on a datagrid that is on the form. The problem is that the thread will slowly take over all of the processor time. After about 8 events, the form will not even respond anymore. Here is the guts of my test code// Class and event for Threausing Systemnamespace ThreadTestStufpublic delegate void TestEventHandler(object sender,int count)public class TestThreadpublic event TestEventHandler TestEventpublic bool stopRunning = falsepublic TestThread({public void RunningThread()int xyz = 0while (!stopRunning)xyz += 1Console.WriteLine("Count: " + xyz.ToString())if (xyz % 1000 == 0)TestEvent(this,xyz)// Form that call the test threa// Data set only has (int count) and (string desc) in iusing Systemusing System.Drawingusing System.Collectionsusing System.ComponentModelusing System.Windows.Formsusing System.Datausing System.Threadingusing ThreadTestStuffnamespace ThreadTespublic class ThreadTestForm : System.Windows.Forms.Forprivate ThreadTest.TestSet testSet1private System.Windows.Forms.DataGrid TestDGprivate System.Windows.Forms.Button StartThreadButtonprivate Thread localThreadprivate TestThread localTestThreadprivate System.ComponentModel.Container components = nullpublic ThreadTestForm(InitializeComponent()protected override void Dispose( bool disposing{localTestThread.stopRunning = truelocalThread.Abort()if( disposingif (components != null)components.Dispose()base.Dispose( disposing )private void InitializeComponent(this.testSet1 = new ThreadTest.TestSet()this.TestDG = new System.Windows.Forms.DataGrid()this.StartThreadButton = new System.Windows.Forms.Button()((System.ComponentModel.ISupportInitialize)(this.t estSet1)).BeginInit()((System.ComponentModel.ISupportInitialize)(this.T estDG)).BeginInit()this.SuspendLayout()//// testSet//this.testSet1.DataSetName = "TestSet"this.testSet1.Locale = new System.Globalization.CultureInfo("en-US")//// TestD//this.TestDG.DataMember = ""this.TestDG.DataSource = this.testSet1.TestTablethis.TestDG.HeaderForeColor = System.Drawing.SystemColors.ControlTextthis.TestDG.Location = new System.Drawing.Point(16, 24)this.TestDG.Name = "TestDG"this.TestDG.Size = new System.Drawing.Size(320, 144)this.TestDG.TabIndex = 0//// StartThreadButto//this.StartThreadButton.Location = new System.Drawing.Point(224, 184)this.StartThreadButton.Name = "StartThreadButton"this.StartThreadButton.Size = new System.Drawing.Size(120, 32)this.StartThreadButton.TabIndex = 1this.StartThreadButton.Text = "Start Thread"this.StartThreadButton.Click += new System.EventHandler(this.StartThreadButton_Click)//// ThreadTestFor//this.AutoScaleBaseSize = new System.Drawing.Size(5, 13)this.ClientSize = new System.Drawing.Size(376, 253)this.Controls.Add(this.StartThreadButton)this.Controls.Add(this.TestDG)this.Name = "ThreadTestForm"this.Text = "Thread Test Form"((System.ComponentModel.ISupportInitialize)(this.t estSet1)).EndInit()((System.ComponentModel.ISupportInitialize)(this.T estDG)).EndInit()this.ResumeLayout(false)#endregio/// <summary/// The main entry point for the application/// </summary[STAThreadstatic void Main()Application.Run(new ThreadTestForm())private void EventHappend(object sender, int countlocalThread.Interrupt()testSet1.TestTable.AddTestTableRow(count,"Hello There")//MessageBox.Show(localThread.ThreadState.ToString() )private void StartThreadButton_Click(object sender, System.EventArgs e{localTestThread = new TestThread();localTestThread.TestEvent += new TestEventHandler(this.EventHappend);localThread = new Thread(new ThreadStart(localTestThread.RunningThread));localThread.Start();localThread.IsBackground = true;}}}Can anyone help?Thanks,Dennis Owens 解决方案 Dennis Owens <an*******@discussions.microsoft.com> wrote: I am trying to run a thread off of a form, and every once in a while the thread will raise an event for the form to read. When the form gets the event, the form will place the event into a dataset and display it on a datagrid that is on the form. The problem is that the thread will slowly take over all of the processor time. After about 8 events, the form will not even respond anymore. Here is the guts of my test code.I''m not surprised - you''ve got 8 threads in a tight loop. That''s boundto take over the processor! However, you''ve got a few other nastiesgoing on...Firstly, you''re accessing stopRunning in a non-thread-safe way. Youshould either declare it as being volatile, or wrap any access to it ina lock.Secondly, you should never update the GUI from a non-UI thread, as youcurrently are doing. You should use Control.Invoke to invoke a delegateon the UI thread.Thirdly, why are you calling localThread.Interrupt() from your event?At that time, you''re actually running *in* the thread you''re trying tointerrupt!--Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeetIf replying to the group, please do not mail me tooThe interrrupt was just a wild guess to try and stop it from sucking up all the processor time. I forgot I left it in there. The only line in that method should be the adding of the row in the dataset. As for your second thing, is this what is causing the thread to take over. Well I will lookup Control.Invoke and see if I can figure it out. I still don''t see the eight threads, just the form and the test threadThanks Dennis Owen Hi,stopRunning doesn''t need to be declared volatile and it should not be usedwith locks.Native integer assignment is atomic operation as well as native integerpromotion (even so the last doesn''t even count).No compiler would optimize away loading of cycle variable when there isnontrivial cycle body (like non-inlined method calls inside of cycle).And you don''t need release/acquire semantic for single variable with atomicassignment.Using LOCK for accessing it would be unnecessary performance hit if not tosay a mistake.I suppose that he misinterpreted meaning of Thread.Interrupt, and you arecorrect with the rest of your comments.-Valery.See my blog at: http://www.harper.no/valery"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in messagenews:MP************************@msnews.microsoft.c om... Dennis Owens <an*******@discussions.microsoft.com> wrote: I am trying to run a thread off of a form, and every once in a while the thread will raise an event for the form to read. When the form gets the event, the form will place the event into a dataset and display it on a datagrid that is on the form. The problem is that the thread will slowly take over all of the processor time. After about 8 events, the form will not even respond anymore. Here is the guts of my test code. I''m not surprised - you''ve got 8 threads in a tight loop. That''s bound to take over the processor! However, you''ve got a few other nasties going on... Firstly, you''re accessing stopRunning in a non-thread-safe way. You should either declare it as being volatile, or wrap any access to it in a lock. Secondly, you should never update the GUI from a non-UI thread, as you currently are doing. You should use Control.Invoke to invoke a delegate on the UI thread. Thirdly, why are you calling localThread.Interrupt() from your event? At that time, you''re actually running *in* the thread you''re trying to interrupt! -- Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeet If replying to the group, please do not mail me too 这篇关于C#,Threads,Events和DataGrids / DataSet的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 1403页,肝出来的..
09-06 21:35