gpt4 book ai didi

c# - 尝试将行添加到数据表时线程进入等待或 sleep 状态

转载 作者:太空宇宙 更新时间:2023-11-03 11:35:13 24 4
gpt4 key购买 nike

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

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

问题是我的编写器线程在尝试将行写入数据表时进入 Wait-Sleep-Join 模式(从线程工具窗口得知)

代码结构是这样的:

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,DataTable 将引发事件。事件是来自 wiforms/wpf 的 Hook 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?

关于c# - 尝试将行添加到数据表时线程进入等待或 sleep 状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6492970/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com