读书人

多线程有关问题高手求救

发布时间: 2012-02-24 16:30:39 作者: rapoo

多线程问题,高手求救!
开了一个新线程往SQLSERVER中导入海量数据,一次性导入数W条的时候正常,一次性导入数十W条的时候报如下错误:

"CLR 无法从 COM 上下文 0x1b0de8 转换为 COM 上下文 ox1b1010,这种状态已持续 60 秒。拥有目标上下文/单元的线程很有可能执行的是非泵式等待或者在不发送 Windows 消息的情况下处理一个运行时间非常长的操作。这种情况通常会影响到性能,甚至可能导致应用程序不响应或者使用的内存随时间不断累积。要避免此问题,所有单线程单元(STA)线程都应使用泵式等待基元(如 CoWaitForMultipleHandles),并在运行时间很长的操作过程中定期发送消息。"
请高手帮忙解决:代码如下:
private void bnResultsInsertSQLDB_Click(object sender, EventArgs e)
{
lbProcessInfoIndex.Visible = true;
tdThread = new Thread(new ThreadStart(fnIndexInsertDB));
tdThread.TrySetApartmentState(ApartmentState.STA);
tdThread.Start();


}
private void fnIndexInsertDB()
{
dsDataSource = CindexSearch.fnReturnDataSource(CMainClass.szDefaultPickAllIndex);
DataTable dtDataSource = CindexSearch.fnAddNewDataColumn(dsDataSource.Tables[ "dtDataSource "], "FileExtension ", 0, 1, 4,lbProcessInfoIndex);
CMainClass.fnIndexInsertSQLDB(dtDataSource, "filemaininfo ", "所有文件索引信息已成功导入数据库! ");
tdThread.Abort();
}
public DataSet fnReturnDataSource(string szKeyWords)
{
CqueryHelper.QuerySelectColumns = "FileName,Path,Size ";
string szSqlQuery = CqueryHelper.GenerateSQLFromUserQuery(szKeyWords);
if(szKeyWords==CMainClass.szDefaultPickAllIndex)
szSqlQuery = szSqlQuery.Substring(0, szSqlQuery.IndexOf( "WHERE ") - 1);
//MessageBox.Show(szSqlQuery);
OleDbConnection odcConnection = new OleDbConnection(CqueryHelper.ConnectionString);
OleDbDataAdapter odaAdapter = new OleDbDataAdapter(szSqlQuery, odcConnection);
DataSet dsDataSource = new DataSet();


odaAdapter.Fill(dsDataSource, "dtDataSource ");
return dsDataSource;
}
public DataTable fnAddNewDataColumn(DataTable dsOldDataTable,string szColumnName,int nTypeCode,int nFileNameLocation,int nFileExtensionLocation,Label lbLabelProcessShow)

{
//临时增加ID行,不可通用。
dsOldDataTable.Columns.Add(new DataColumn( "ID ", typeof(System.Int32)));
dsOldDataTable.Columns[ "ID "].SetOrdinal(0);
//*
dsOldDataTable.Columns[ "filename "].SetOrdinal(1);
dsOldDataTable.Columns[ "path "].SetOrdinal(2);
dsOldDataTable.Columns[ "size "].SetOrdinal(3);
//
if (nTypeCode == 0)
{
dsOldDataTable.Columns.Add(new DataColumn(szColumnName, typeof(System.String)));
}
else { //预留以增加其它DataType
}
for (int i = 0; i < dsOldDataTable.Rows.Count; i++)
{
//临时增加ID行,不可通用。
dsOldDataTable.Rows[i][0] = i + 1;
//*
if (dsOldDataTable.Rows[i][nFileNameLocation].ToString().LastIndexOf( ". ") > 0)
{
dsOldDataTable.Rows[i][nFileExtensionLocation] = dsOldDataTable.Rows[i][nFileNameLocation].ToString().Substring(dsOldDataTable.Rows[i][nFileNameLocation].ToString().LastIndexOf( ". "), dsOldDataTable.Rows[i][nFileNameLocation].ToString().Length - dsOldDataTable.Rows[i][nFileNameLocation].ToString().LastIndexOf( ". "));


}
CFileOperation.fnSetLabelText(lbLabelProcessShow, Convert.ToString(i + 1) + "/ " + dsOldDataTable.Rows.Count.ToString() + "文件,正在处理: " + dsOldDataTable.Rows[i][nFileNameLocation].ToString());


}
return dsOldDataTable;
}
public void fnIndexInsertSQLDB(DataTable dtDataSource,string szSQLTableName,string szShowSuccessInfo)
{
scdCommand.CommandText = "delete from "+szSQLTableName;
try
{
scdCommand.ExecuteNonQuery();
}
catch (Exception exMessage)
{ //错误信息处理
fnInsertSQLDBException(Login.szUserName, exMessage.Message, DateTime.Now);
}
SqlBulkCopy sbcBulkCopy = new SqlBulkCopy(szSQLConnection, SqlBulkCopyOptions.UseInternalTransaction);
sbcBulkCopy.BulkCopyTimeout = 500000000;
sbcBulkCopy.NotifyAfter = dtDataSource.Rows.Count;
sbcBulkCopy.DestinationTableName = szSQLTableName;

try
{
sbcBulkCopy.WriteToServer(dtDataSource);
}
catch (Exception exMessage)
{ //错误信息处理


fnInsertSQLDBException(Login.szUserName, exMessage.Message, DateTime.Now);
}
MessageBox.Show(szShowSuccessInfo);
}

[解决办法]
我猜测问题并非出在线程本身,而是由于线程与主线程等的资源共享问题

[解决办法]
太复杂了
[解决办法]
真不好意思
看了你的问题,我想没几个是真的会认真去为你解决的
实在要花一定时间才行
帮你顶了
[解决办法]
你这个错误未必和多线程一定有关,你可以把fnIndexInsertDB放在主线程里运行试一下.

如果在主线程里也有同样问题,尝试把数据分批导入,我感觉一次造一个巨大的SQL串加入几十万条记录不太好.

读书人网 >C#

热点推荐