У меня тут небольшая дилемма.У меня есть эта настройка с включенным BackgroundWorker:
#region Locum List
private Object DoWorkMain_LocumList() {
#region Query
var locums = from locum in DbContext.Locums
where
locum.IsActive == true &&
locum.IsAdminMarkedComplete == true &&
locum.IsLocumsExciteBan == false &&
locum.IsGPHCBan == false &&
locum.LocumWorkingPreferenceID == 1
select new {
LocumID = locum.OID,
LocumName = locum.FirstName + " " + locum.LastName,
locum.MobileNumber,
locum.Email,
Gender = locum.Gender ? "Male" : "Female",
locum.DateofBirth,
LocumType = locum.LocumType.Name,
Distance = DbContext.GetDistanceFromCache(TextAddressPostCode.Text.Trim(), locum.AddressInfo.Postcode),
Address = String.Format("{0} {1} {2} {3}",
locum.AddressInfo.House.Length == 0 ? String.Empty : locum.AddressInfo.House + ", ",
locum.AddressInfo.Street.Length == 0 ? String.Empty : locum.AddressInfo.Street + ", ",
locum.AddressInfo.Area.Length == 0 ? String.Empty : locum.AddressInfo.Area + ", ",
locum.AddressInfo.Postcode ?? String.Empty),
Postcode = locum.AddressInfo.Postcode,
City = locum.AddressInfo.City.Name,
County = locum.AddressInfo.City.County.Name,
locum.SystemUserID,
Status = DbContext.GetJobPermanentProcessLatestStatus(VaccanyID, locum.OID)
};
#endregion
DataTable LocumListX = new DataTable("LocumList");
DataColumn PrimaryColumn = LocumListX.Columns.Add("LocumID", typeof(Int64));
LocumListX.Columns.Add("LocumName", typeof(String));
LocumListX.Columns.Add("MobileNumber", typeof(String));
LocumListX.Columns.Add("Email", typeof(String));
LocumListX.Columns.Add("Gender", typeof(String));
LocumListX.Columns.Add("DateofBirth", typeof(DateTime));
LocumListX.Columns.Add("LocumType", typeof(String));
LocumListX.Columns.Add("Distance", typeof(Decimal));
LocumListX.Columns.Add("Address", typeof(String));
LocumListX.Columns.Add("Postcode", typeof(String));
LocumListX.Columns.Add("City", typeof(String));
LocumListX.Columns.Add("County", typeof(String));
LocumListX.Columns.Add("SystemUserID", typeof(Int64));
LocumListX.Columns.Add("Status", typeof(String));
LocumListX.PrimaryKey = new DataColumn[] { PrimaryColumn };
int iCurrentRowIndex = 0;
#region DataTable
int LocumListXRowsCount = locums.Count();
foreach (var item in locums) {
DataRow newRow = LocumListX.NewRow();
newRow["LocumID"] = item.LocumID;
newRow["LocumName"] = item.LocumName;
newRow["MobileNumber"] = item.MobileNumber;
newRow["Email"] = item.Email;
newRow["Gender"] = item.Gender;
newRow["DateofBirth"] = item.DateofBirth;
newRow["LocumType"] = item.LocumType;
newRow["Distance"] = item.Distance;
newRow["Address"] = item.Address;
newRow["Postcode"] = item.Postcode;
newRow["City"] = item.City;
newRow["County"] = item.County;
newRow["SystemUserID"] = item.SystemUserID;
newRow["Status"] = item.Status;
LocumListX.Rows.Add(newRow);
iCurrentRowIndex++;
BackgroundWorkerLocumList.ReportProgress((int)(iCurrentRowIndex * 100F / (LocumListXRowsCount - 1)));
}
#endregion
LocumListXRowsCount = LocumListX.Rows.Count;
iCurrentRowIndex = 0;
foreach (DataRow Row in LocumListX.Rows) {
if (Convert.ToDecimal(Row["Distance"]) >= 0) {
iCurrentRowIndex++;
continue;
}
Row["Distance"] = GetDistanceBetween(Row);
iCurrentRowIndex++;
BackgroundWorkerLocumList.ReportProgress((int)(iCurrentRowIndex * 100F / (LocumListXRowsCount - 1)));
if (BackgroundWorkerLocumList.CancellationPending) {
return null;
}
}
return LocumListX;
}
private void BackgroundWorkerLocumList_DoWork(object sender, DoWorkEventArgs e) {
BackgroundWorker backgroundWorkerLocumList = sender as BackgroundWorker;
try {
if (backgroundWorkerLocumList != null) {
backgroundWorkerLocumList.ReportProgress(0);
if (backgroundWorkerLocumList.CancellationPending) {
e.Cancel = true;
return;
}
e.Result = DoWorkMain_LocumList();
}
}
catch (Exception ex) {
e.Result = ex;
}
}
private void BackgroundWorkerLocumList_ProgressChanged(object sender, ProgressChangedEventArgs e) {
ProgressBarLocumList.EditValue = e.ProgressPercentage;
}
private void BackgroundWorkerLocumList_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
LoadLocumList_ResetProgress();
if (e.Cancelled) {
XtraMessageBox.Show("The task has been canceled");
}
else if (e.Error != null) {
FormHelpers.ShowErrorMessageBox("Error while looking up distances.", Text, e.Error);
}
else {
#region Grid
GridLocumList.DataSource = e.Result as DataTable;
LoadLocumListGridSetup();
#endregion
}
ButtonRefreshLocumList.Enabled = true;
}
#endregion
Что происходит, если исходный LINQ должен возвращать от 1000 до 1500 записей.Поэтому, когда на более позднем этапе я выполняю For For для преобразования LINQ в DataTable (foreach (var item in locums)
), я сталкиваюсь с серьезными паузами, и вскоре поток просто умирает без какого-либо предупреждения.Я вручную преобразовываю LINQ в DataTable, потому что раньше я использовал метод расширения MoreLinq, но это также заняло очень много времени, поскольку отчеты о ходе работ не требовались, а моему клиенту это не нравится.
У меня есть две идеи и третья вещьЭто сильная головная боль.
One: Если я могу перечислить результат с предложением where.уникальный столбец - LocumID.Если я смогу создать Список всех LocumID из результатов 1000-1500, а затем использовать Для каждого в Списке LocumID, чтобы я имел дело с одной строкой LINQ за раз, чтобы построить свой DataTable.
Два: Реализуйте .Skip () и .Take () для обработки данных в виде кусков по 50.
Есть предложения?
С уважением.