[英]How to update a DataTable created on Main Thread by a new thread in C#?
我有一個名為“ DTImageList”的全局數據表和一個名為“ uxImageGrid”的XtraGrid。 現在有一個名為“ prcFillImagesVideosAndFiles”的方法,在該方法中,我們從數據庫頁面明智地獲取圖像數據,即一次說500行,然后根據數據的總存在量,使用XtraTabControl在網格頂部創建手動頁面。搜索。 假設我們獲得700張圖片,那么一次只能加載500張圖片,並且將創建2個頁面,分別為“第1頁”,“第2頁”。 但是在“ prcFillImagesVideosAndFiles”方法中,我們不獲取實際圖像,而僅獲取其名稱,id等。此后,我創建了一個新線程並調用了一個方法運行器,該運行器又調用了一個名為“ FillImages”的新方法,在其中查找DTImageList並從后端一路帶來實際圖像,並使用此圖像更新行,因此XtraGrid開始一一顯示圖像。 此過程在幾分鍾內可以正常工作,即加載20-25張圖像,然后出現“跨線程操作無效”錯誤。
//我的prcFillImagesVideosAndFiles方法的代碼是:
`if (DTImageList != null)
{
DTImageList.Rows.Clear(); DTImageList.Columns.Clear(); DTImageList = null;
}
string sql = @"select " + top + @" IM.Image_ID,IM.extension,IM.Is_Uploaded,cast(0 as varbinary) 'ActualImage',IM.description 'Description',IM.ContentType,IM.DateTime_Uploaded,IM.FolderName, '' as FilePath
from images as IM where IM.GCRecord is null and IM.Is_Uploaded=1 " + MainCriteria + @" " + Ob + @"";
string sql1 = LayoutPaging(sql);
DTImageList = new DataTable();
DTImageList = FillDataTable(sql1);
DataTable DTdeliv2 = new DataTable();
DTdeliv2.Columns.Add("Image");
DTdeliv2.Columns.Add("UniqueNumber");
DTdeliv2.Columns["Image"].DataType = typeof(Image);
DTdeliv2.Columns["UniqueNumber"].DataType = typeof(int);
DTImageList.Merge(DTdeliv2, true, MissingSchemaAction.Add);
uxImageGrid.DataSource = null;
uxImageGrid.DataSource = DTImageList;
RepositoryItemTextEdit riTextEdit = new RepositoryItemTextEdit();
riTextEdit.Appearance.TextOptions.HAlignment = HorzAlignment.Center;
layoutView1.Columns["Description"].AppearanceCell.TextOptions.HAlignment = HorzAlignment.Center;
riTextEdit.Appearance.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(128)))), ((int)(((byte)(128)))));
riTextEdit.Appearance.Options.UseBackColor = true;
riTextEdit.NullText = "";
uxImageGrid.RepositoryItems.Add(riTextEdit);
layoutView1.Columns["Description"].ColumnEdit = riTextEdit;
riTextEdit.Leave += new EventHandler(riTextEdit_Leave);
riTextEdit.KeyPress += new KeyPressEventHandler(riTextEdit_KeyPress);
RepositoryItemPictureEdit riPictureEdit = new RepositoryItemPictureEdit();
riPictureEdit.SizeMode = PictureSizeMode.Zoom;
riPictureEdit.ShowMenu = false;
riPictureEdit.NullText = " Loading Image";
riPictureEdit.Appearance.Image = Pionero.RetailTherapy.Properties.Resources.mag;
uxImageGrid.RepositoryItems.Add(riPictureEdit);
layoutView1.Columns["Image"].ColumnEdit = riPictureEdit;
riPictureEdit.MouseMove += new MouseEventHandler(riPictureEdit_MouseMove);
riPictureEdit.MouseDown += new MouseEventHandler(riPictureEdit_MouseDown);
layoutView1.Columns["Image"].Caption = "";
int k = DTImageList.Rows.Count;
if (k > 0)
{
DevExpress.Data.Filtering.CriteriaOperator expr1 = new DevExpress.Data.Filtering.BinaryOperator("Is_Uploaded", true);
layoutView1.ActiveFilterCriteria = expr1;
if (pthread != null)
{
StopRunningThread();
}
if (pthread == null || pthread.IsAlive==false)
{
pthread = new Thread(new ThreadStart(runner));
pthread.IsBackground = true;
Is_ThreadNeededtoWork = true;
pthread.Start();
}
else
{
Is_ThreadNeededtoWork = true;
pthread.Start();
}
}`
// Runner方法是:
void runner()
{
if (Is_ThreadNeededtoWork == false)
{
if (dtImages != null)
{
dtImages.Rows.Clear(); dtImages.Columns.Clear(); dtImages = null;
}
return;
}
if (Is_ThreadNeededtoWork == true)
{
FillImages();
}
}
// FillImages方法的代碼為:
try
{
if (DTImageList.Rows.Count <= 0) return;
StringBuilder sbImagesNotLoaded = new StringBuilder();
sbImagesNotLoaded.Append("Following images not loaded due to connection: ");
ArrayList lstImage_IDs = new ArrayList();
int NoOfAttempts = 0;
//if (dtImages != null)
//{
for (int i = 0; i < DTImageList.Rows.Count; i++)
{
NoOfAttempts = 0;
V:
string Qry = @" Select Image_ID,image from images where Image_ID = " + DTImageList.Rows[i]["Image_ID"].ToString();
dtImages = FillDataTable(Qry);
if (dtImages != null && dtImages.Rows.Count > 0)
{
if (DTImageList.Rows[i]["image"] == DBNull.Value)
{
// Thread.Sleep(100);
byte[] barr = (byte[])dtImages.Rows[0]["image"];
Image img = Global.byteArrayToImage(barr);
DTImageList.Rows[i]["Image"] = img;
DTImageList.AcceptChanges();
uxImageGrid.RefreshDataSource();
}
}
else
{
// Thread.Sleep(100);
if (Convert.ToInt32(DTImageList.Rows[i]["Image_ID"]) > 0)
if (NoOfAttempts < 3)
{
NoOfAttempts = NoOfAttempts + 1;
goto V;
}
else
{
if (lstImage_IDs.Count > 0)
sbImagesNotLoaded.Append("," + Convert.ToString(DTImageList.Rows[i]["Description"]));
else
sbImagesNotLoaded.Append(Convert.ToString(DTImageList.Rows[i]["Description"]));
lstImage_IDs.Add(DTImageList.Rows[i]["Image_ID"]);
}
}
}
//}
if (lstImage_IDs.Count > 0)
{
for (int i = 0; i < lstImage_IDs.Count; i++)
{
DataRow drImage = DTImageList.Select("Image_ID=" + Convert.ToString(lstImage_IDs[i]) + "").FirstOrDefault();
if (drImage != null)
DTImageList.Rows.Remove(drImage);
}
DTImageList.AcceptChanges();
XtraMessageBox.Show(sbImagesNotLoaded.ToString(), Global.Header, MessageBoxButtons.OK, MessageBoxIcon.Information);
}
EnableDisablePanelControls(true);
if (pthread != null)
{
Is_ThreadNeededtoWork = false;
StopRunningThread();
}
}
catch (ThreadAbortException abortException)
{
}
catch (Exception emmp)
{
EnableDisablePanelControls(true);
//pthread.Abort();
}
finally
{
//Global.StopProg();
}
// StopRunningThread()的代碼是:
void StopRunningThread()
{
if (dtImages != null)
{
dtImages.Rows.Clear(); dtImages.Columns.Clear(); dtImages = null;
}
Is_ThreadNeededtoWork = false;
}
謝謝薇琪
您可以嘗試插入圖像,然后再將其作為數據源傳遞給uxImageGrid。 將圖像列添加到DTImageLis。 DTImageList.Columns.Add(“ Image”,typeof(System.Drawing.Image));
根據Name,Id等將圖像添加到數據表中,並將其綁定到uxImageGrid uxImageGrid.Datasource = DTImageList;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.