Insert parent-child rows using Parallel programming - c#

I have a method that iterates the rows using for loop and inside that for loop call the DNN API that inserts a parent child row into the database. The maximum to insert the data is 1000 rows per execution. I tested it on my local machine the performance is very slow. I am thinking to use a Parallel Programming, but not sure on how to implement this since there is a dependency on data insertion because of parent child relationship. And I am not sure if this is a good approach to use Parallel programming. Any help please?
Sample code
private void AddTab()
{
for (i = 0; i < 1000; i++) {
TabController tabController = new TabController();
var portalSettings = new
DotNetNuke.Entities.Portals.PortalSettings(info.PortalId);
TabInfo tab = new TabInfo();
tab.PortalID = info.PortalId;
tab.TabName = info.TabName;
tab.Title = info.Title;
tab.Description = info.TabName;
tab.KeyWords = info.TabName;
tab.IsVisible = info.IsVisible;
tab.DisableLink = info.IsDisabled;
tab.ParentId = info.ParentId == null ? Null.NullInteger : info.ParentId.GetValueOrDefault();
tab.IsDeleted = false;
tab.Url = "";
tab.SkinSrc = "[G]Skins/HRT.Portal.DNNThemes.Default/Home.ascx";
tab.ContainerSrc = portalSettings.DefaultPortalContainer;
tab.IsSuperTab = false;
var parentPage = tabController.GetTab(portalSettings.HomeTabId, info.PortalId);
//clone parent page permissions
foreach (TabPermissionInfo permission in parentPage.TabPermissions.ToList())
{
tab.TabPermissions.Add(permission);
}
int tabId = tabController.AddTab(tab, true);
}
}

Related

c# lucene 4.8 slow search: 400ms -> to 30ms?

i try to speed up my lucene-search in my wpf-application.
i hoped that my search would be in the range of about 30ms.
87 search items where found in the index. So that is not very much.
But Stopwatch timer says, it takes around 400ms, way to much for me.
So can u check my code, how i can improve code ?
I also still measured time from the beginning of the try block to the foreach, so there is no big waste of time through init; but it is not (0 ms).
List<CardView> aAll_CardView = new List<CardView>();
try
{
SortField field = new SortField(LUCENT_STATE_MAIN, SortFieldType.STRING);
Sort sort = new Sort(field);
searchManager.MaybeRefreshBlocking(); // execute with fresh index searcher
var searcher = searchManager.Acquire();
var topDocs = searcher.Search(aBooleanQuery, 100, sort);
var _totalHits = topDocs.TotalHits;
CardView aCardView = null;
// measured time: take ~400-500ms grr !!!!
foreach ( var result in topDocs.ScoreDocs)
{
#region iterate through findings and put lucene data into CardView list
var aDoc = searcher.Doc(result.Doc);
aAll_CardView.Add(new CardView
{
// all fields are defined as TextField()...
// must be first, because used in e.g. Nr_Main
RelatedItemCount = aDoc.Get(LUCENT_RELATED_ITEMS),
Nr_Main = aDoc.Get(LUCENT_NR_MAIN),
Nr_Parent = aDoc.Get(LUCENT_NR_PARENT),
Antwort = aDoc.Get(LUCENT_ANTWORT),
Beschreibung = aDoc.Get(LUCENT_BESCHREIBUNG),
Note = aDoc.Get(LUCENT_NOTES),
Question_Main = aDoc.Get(LUCENT_TITLE_MAIN),
Question_Parent = aDoc.Get(LUCENT_TITLE_PARENT),
Book = aDoc.Get(LUCENT_BOOK),
Date_Create = aDoc.Get(LUCENT_DATE_CREATED),
Date_LastEdit = aDoc.Get(LUCENT_DATE_LASTEDIT),
Bibelstelle = aDoc.Get(LUCENT_BIBELSTELLE),
// ParseCore just uses TryParse to get enum for state
Status_Main = ParseCore(aDoc.Get(LUCENT_STATE_MAIN)),
Status_Parent = ParseCore(aDoc.Get(LUCENT_STATE_PARENT))
});
#endregion
}
}
catch(Exception e)
{
string exp = e.ToString();
new JMsg(exp).ShowDialog();
}
finally
{
}

Apply any kind of Updates on database immedieately C#

I have this program where I want to create a button base from Products on my database(ProductTbl). I found a way to do that
Here's the code:
public void DynamicButton() //Function for retrieving record and creating a button for each product
{
string select = "select ProductID,ProductDesc,ProductPrice,ProductPic from ProductTbl" ;
sda = new SqlDataAdapter(select,sqlConn);
sda.Fill(dataTable);
for (int i = 0; i < dataTable.Rows.Count; i++)
{
ExtendedButton prodBtn = new ExtendedButton(); //with ExtendedButton this time
prodBtn._itemName = dataTable.Rows[i][1].ToString();//this asigns the product name to the extended button
prodBtn._itemID = Convert.ToInt32(dataTable.Rows[i][0]);
prodBtn._myPrice = Convert.ToDecimal(dataTable.Rows[i][2]);
prodBtn.BackgroundImageLayout = ImageLayout.Stretch;
prodBtn.Click += new EventHandler(OnButtonClick);
prodBtn.Height = 100;
prodBtn.Width = 100;
System.Drawing.Font f1 = SystemFonts.DefaultFont;
prodBtn.Font = new System.Drawing.Font(f1.FontFamily,f1.Size,FontStyle.Bold);
prodBtn.Text = dataTable.Rows[i][1].ToString();
prodBtn.TextAlign = ContentAlignment.BottomCenter;
prodBtn.ForeColor = Color.White;
prodBtn.BackgroundImageLayout = ImageLayout.Zoom;
toolTip1.Show(prodBtn.Text, prodBtn);
byte[] image = (byte[])dataTable.Rows[i][3];
prodBtn.BackgroundImage = imgConverter.byteArrayToImage(image);
prodBtn.TextAlign = ContentAlignment.MiddleCenter;
flowPanel.Controls.Add(prodBtn);
}
}
//You can see this at codeproject
Now the problem is that whenever i add a product on that table using Stored procedure. I don't know how i can sync updates to the datatable that I use with this one. Any ideas and suggestion will be highly appreciated. Thanks sorry for the long post
You can use ASP.Net Caching with SqlCacheDependency.
See this page for details:
https://msdn.microsoft.com/en-us/library/ms178604.aspx

Possible Leak when reading content?

I created a tool which iterates through all Commits of a repository.
Then it makes a diff of the commit to all of its parents and then reads the content for some checks.
Now it came out that this slows down very quickly. It always slows down after the same specific commit which is quite large as it is a merge commit.
Here the code how I iteratre through the commits. The following codes are a little simplified for a better focus.
var repo = new Repository(path);
foreach (LibGit2Sharp.Commit commit in repo.Commits)
{
IEnumerable<FileChanges> changed = repo.GetChangedToAllParents(commit);
var files = ResolveChangeFileInfos(changed);
var entry = new Commit(commit.Id.ToString(), commit.Author.Email, commit.Committer.When, commit.Message, files);
yield return entry;
}
in GetChagedToAllParents I basically make a diff foreach parent like this
foreach(var parent in commit.parent)
{
var options = new CompareOptions
{
Algorithm = DiffAlgorithm.Minimal,
IncludeUnmodified = false
};
var patches = repo.Diff.Compare<Patch>(parent.Tree, commit.Tree, options); // Difference
}
and later I read the content of the files in this way:
var blob = repo.Lookup<Blob>(patchEntry.Oid.Sha); // Find blob
Stream contentStream = blob.GetContentStream();
string result = null;
using (var tr = new StreamReader(contentStream, Encoding.UTF8))
{
result = tr.ReadToEnd();
}
Are there any known issues ? am I missing any leaks?
Update
I Found out that most of the time (about 90%) is taken by the diff. and it gets constantly slower
var options = new CompareOptions
{
Algorithm = DiffAlgorithm.Minimal,
IncludeUnmodified = false
};
var patches = repo.Diff.Compare<Patch>(parent.Tree, commit.Tree, options); // Difference
I can reproduce it with this code:
var repo = new Repository(path);
foreach (var commit in repo.Commits)
{
pos++;
if (pos%100 == 0)
{
Console.WriteLine(pos);
}
var options = new CompareOptions
{
Algorithm = DiffAlgorithm.Minimal,
IncludeUnmodified = false,
Similarity = new SimilarityOptions
{
RenameDetectionMode = RenameDetectionMode.None,
WhitespaceMode = WhitespaceMode.IgnoreAllWhitespace
}
};
foreach (var parent in commit.Parents)
{
var changedFiles=
repo.Diff.Compare<TreeChanges>(parent.Tree, commit.Tree, options).ToList();
}
}
it reserved about 500MB for each 1000 commits and at some point it just crashes. So I posted it also here:
https://github.com/libgit2/libgit2sharp/issues/1359
Is there a faster way to get all files that were changed in a specific commit?

Creating dynamic columns and data binding

I am using ObjectListView to display information regarding virtual machines and each virtual machine has a different set of drives attached to it. During my data gathering, I get all of the info and store it in a Disk_Drive object with the properties that I care for (size,serial,usage,etc), now I want to dynamically create the columns and then bind the data using AddObjects. How would I do this?
I am not sure what the aspect getter should be in this scenario as it will not be unique, how can I handle this?
public void GenerateColumns(Model.HyperVTools.VMInfo vmObject)
{
objectListView2.Columns.Clear();
objectListView2.Items.Clear();
List<OLVColumn> columnsList = new List<OLVColumn>();
OLVColumn vmhostnameColumn = new OLVColumn("Hostname", "Host");
//vhd columns
foreach (var disk in vmObject.DisksList)
{
string text = string.Format("{0};{1}GB;{2}GB;", disk.Path, disk.SizeReadable,
disk.MaxVHDSizeReadable);
disk.FormattedVHDInfo = text;
OLVColumn diskColumn = new OLVColumn("Attached VHD", "FormattedVHDInfo");
columnsList.Add(diskColumn);
}
columnsList.Add(vmhostnameColumn);
objectListView2.Columns.AddRange(columnsList.Cast<System.Windows.Forms.ColumnHeader>().ToArray());
objectListView2.AddObject(vmObject);
}
Try this:
DataTable dtInput = new DataTable();
dtInput = dsAnalystPage.Tables[0];
foreach (DataColumn cl in dtInput.Columns)
{
BrightIdeasSoftware.OLVColumn aNewColumn = new BrightIdeasSoftware.OLVColumn();
aNewColumn.Name = cl.ColumnName;
aNewColumn.Text = cl.ColumnName;
if (aNewColumn.Text == "ASF_Code" || aNewColumn.Text == "ASD_SheetCode" || aNewColumn.Text == "ASD_SheetName")
{
aNewColumn.Width = 0;
aNewColumn.IsVisible = false;
}
OLV.AllColumns.Add(aNewColumn);
OLV.RebuildColumns();
}
Try resetting the control.
OLV.Reset();

Paging using Lucene.net

I'm working on a .Net application which uses Asp.net 3.5 and Lucene.Net I am showing search results given by Lucene.Net in an asp.net datagrid. I need to implement Paging (10 records on each page) for this aspx page.
How do I get this done using Lucene.Net?
Here is a way to build a simple list matching a specific page with Lucene.Net. This is not ASP.Net specific.
int first = 0, last = 9; // TODO: Set first and last to correct values according to page number and size
Searcher searcher = new IndexSearcher(YourIndexFolder);
Query query = BuildQuery(); // TODO: Implement BuildQuery
Hits hits = searcher.Search(query);
List<Document> results = new List<Document>();
for (int i = first; i <= last && i < hits.Length(); i++)
results.Add(hits.Doc(i));
// results now contains a page of documents matching the query
Basically the Hits collection is very lightweight. The cost of getting this list is minimal. You just instantiate the needed Documents by calling hits.Doc(i) to build your page.
What I do is iterate through the hits and insert them into a temporary table in the db. Then I can run a regular SQL query - joining that temp table with other tables too - and give the grid the DataSet/DataView that it wants.
Note that I do the inserts and the query in ONE TRIP to the db, because I'm using just one SQL batch.
void Page_Load(Object sender, EventArgs e)
{
dbutil = new DbUtil();
security = new Security();
security.check_security(dbutil, HttpContext.Current, Security.ANY_USER_OK);
Lucene.Net.Search.Query query = null;
try
{
if (string.IsNullOrEmpty(Request["query"]))
{
throw new Exception("You forgot to enter something to search for...");
}
query = MyLucene.parser.Parse(Request["query"]);
}
catch (Exception e3)
{
display_exception(e3);
}
Lucene.Net.Highlight.QueryScorer scorer = new Lucene.Net.Highlight.QueryScorer(query);
Lucene.Net.Highlight.Highlighter highlighter = new Lucene.Net.Highlight.Highlighter(MyLucene.formatter, scorer);
highlighter.SetTextFragmenter(MyLucene.fragmenter); // new Lucene.Net.Highlight.SimpleFragmenter(400));
StringBuilder sb = new StringBuilder();
string guid = Guid.NewGuid().ToString().Replace("-", "");
Dictionary<string, int> dict_already_seen_ids = new Dictionary<string, int>();
sb.Append(#"
create table #$GUID
(
temp_bg_id int,
temp_bp_id int,
temp_score float,
temp_text nvarchar(3000)
)
");
lock (MyLucene.my_lock)
{
Lucene.Net.Search.Hits hits = null;
try
{
hits = MyLucene.search(query);
}
catch (Exception e2)
{
display_exception(e2);
}
// insert the search results into a temp table which we will join with what's in the database
for (int i = 0; i < hits.Length(); i++)
{
if (dict_already_seen_ids.Count < 100)
{
Lucene.Net.Documents.Document doc = hits.Doc(i);
string bg_id = doc.Get("bg_id");
if (!dict_already_seen_ids.ContainsKey(bg_id))
{
dict_already_seen_ids[bg_id] = 1;
sb.Append("insert into #");
sb.Append(guid);
sb.Append(" values(");
sb.Append(bg_id);
sb.Append(",");
sb.Append(doc.Get("bp_id"));
sb.Append(",");
//sb.Append(Convert.ToString((hits.Score(i))));
sb.Append(Convert.ToString((hits.Score(i))).Replace(",", ".")); // Somebody said this fixes a bug. Localization issue?
sb.Append(",N'");
string raw_text = Server.HtmlEncode(doc.Get("raw_text"));
Lucene.Net.Analysis.TokenStream stream = MyLucene.anal.TokenStream("", new System.IO.StringReader(raw_text));
string highlighted_text = highlighter.GetBestFragments(stream, raw_text, 1, "...").Replace("'", "''");
if (highlighted_text == "") // someties the highlighter fails to emit text...
{
highlighted_text = raw_text.Replace("'","''");
}
if (highlighted_text.Length > 3000)
{
highlighted_text = highlighted_text.Substring(0,3000);
}
sb.Append(highlighted_text);
sb.Append("'");
sb.Append(")\n");
}
}
else
{
break;
}
}
//searcher.Close();
}

Categories

Resources