【问题标题】:Thread Goes in Wait or Sleep state when trying to Add rows to Datatable尝试将行添加到数据表时线程进入等待或睡眠状态
【发布时间】:2011-06-27 12:39:37
【问题描述】:

我创建了一个调用网络服务器的线程 - 读取一些数据 - 将行写入数据表

我的当前线程 - 等待新行到达 - 将数据传递给系统

问题是我的编写器线程在尝试将行写入数据表时进入了等待-睡眠-加入模式(从线程工具窗口得知)

代码结构是这样的:

class DataRetriever
{
    Thread GetReport;

    private DataTable ServerData;

    int rowCount = 0;

    private int _lastReadedRowNo = -1;

    public GetData()
    {
        thrGetReport = new Thread(new ThreadStart(fn_thrGetReport));
                thrGetReport.Name = "CallServer";
                thrGetReport.IsBackground = true;
                thrGetReport.Start();
    }

    //Writer Thread Executes this
    private void fn_thrGetReport()
        {
            for (int i = 0; i < cnt; i++)
            {
                DataRowCollection drcTemp = server.GetAnswer(parameter);

                for (int j = 0; j < drcTemp.Count; j++)
                {                    
                    ServerData.Rows.Add(drcTemp[j].ItemArray); // Here thread goes in Sleep/wait Mode
                    Interlocked.Increment(ref rowCount);
                }
            }

        }

    //This executes in Current Thread
     public bool Read
        {
            get
            {        
                if (no more data to ask condition)
                {
                    return false;
                }
                else
                {
                    //wait till new rows are not entered                                      
                     while (rowCount <= (_lastReadRowNo + 1) ) //Writer thread is in sleep/wait mode so this piece of code executes infinetly
                     ;                    


                    while (Condition Here)
                    {
                        // Read Datarows here 
                //Copy the Read rows to some _toReturndt
                        i++;
                    }

                    _lastReadRowNo = i - 1;
                    return true;
                }
            }
        }


        public DataRowCollection GetNextData()
        {
           DataTable temp = _toReturnDt;
            _toReturnDt.Rows.Clear();
            return temp.Rows;
        }
}


public class DataProcessor
{

    public GetnProcess()
    {
        DataRetriever DataRetriever1 = new DataRetriever();
        DataRetriever1.GetData();

        while (this.DataRetriever1.Read)
        {
            DataRowCollection drc = this.DataRetriever1.GetNextData();
        }
    }
}

【问题讨论】:

  • DataTable 是绑定到某个 UI 控件还是其他地方?
  • 是的,它绑定到 datagridview ,这就是它给我错误的原因。谢谢 TcKs。

标签: c# multithreading race-condition


【解决方案1】:

问题是,如果将行添加到 DataTable 中,DataTable 将引发事件。事件是来自 wiforms/wpf 的挂钩 UI 控件。事件引发后控件“想做事”,但当前线程不是UI线程,而是工作线程。这是问题的核心。

解决方案是在工作线程中加载数据表单服务器,但在 UI 线程中向 DataTable 添加行。

DataRetriever.LoadDataFromServer( this.gridView1, this.myDataTable );
// ... elsewhere ...
public class DataRetriever {
    // uiSynchronizer can run delegates in UI thread
    // uiSynchronizer can be instance of "System.Windows.Forms.Control" (or derived) class
    public void LoadDataFromServer( ISynchronizeInvoke uiSynchronizer, DataTable target ) {
        // QueueUserWorkItem runs delegate in separated thread
        ThreadPool.QueueUserWorkItem((_state)=>{
            // getting rows from server
            var serverRows = server.GetAnswer(parameter);

            // addRows delegate must be called on UI thread
            Action addRows = ()=> {
                try {
                    target.BeginLoadData();
                    foreach(DataRow in serverRow in serverRows) {
                        target.Rows.Add( serverRow.ItemArray );
                    }
                }
                finally {
                    target.EndLoadData();
                }
            };

            // uiSynchronizer.Invoke runs "addRows" delegate on UI thread
            uiSynchronizer.Invoke(addRows);
        });
    }
}

编辑:

关于 Winforms 中的多线程的好文章在 CodeProject 上:What's up with BeginInvoke?

【讨论】:

    猜你喜欢
    • 2013-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-21
    • 2020-02-11
    • 1970-01-01
    • 2017-06-23
    • 1970-01-01
    相关资源
    最近更新 更多