Archive

Archive for the ‘Whatever’ Category

Finally have my own BLOG up!

June 25th, 2017 Michael Bell No comments

Only took a few years… but finally here. So I will post both code and daily life ramblings here :)

Categories: Whatever Tags:

.NET Time Picker Control

June 25th, 2017 Michael Bell 6 comments

I got this into a “release” state today.. and thought I’d put it out there for anyone who wants to use it. It’s a Windows looking time picker control. Have a look!

http://www.MichaelKBell.com/TimePicker

Categories: ASP.NET, Whatever, c# Tags:

Validation against Controls outside of the current NamingContainer

June 25th, 2017 Michael Bell 1 comment

I had a situation where I needed to do this recently. I googled of course, and came up with an overloaded FindControl method. I implemented this in my code, and all seemed well. UNTIL… came the time to get the data posted from my control. I had controls nested in a UserControl, and that usercontrol nested within a FormView. When the postback occurred, I was able to retrieve all values from controls directly in the formview but none from within the controls inside my usercontrol. A buddy of mine helped me out on this, and believe me.. it was no fun tracking down. the values “not being posted” was actually a flaw in the FindControl method override. Please use this piece of code in the naming container that your validators reside, if they in fact need to validate against controls outside:

protected override Control FindControl(string id, int pathOffset)
{
Control c = base.FindControl(id, pathOffset);
if (c != null)
return c;
return FindControl(Page, id);
}
public Control FindControl(Control parent, string id)
{
Control recurse;
if (parent.ID == id)
{
return parent;
}
foreach (Control child in parent.Controls)
{
recurse = FindControl(child, id);
if (recurse != null)
{
return recurse;
}
}
return null;
}
Categories: ASP.NET, Uncategorized, Whatever, c# Tags:

Efficient Hit Logging with ASP.NET 2.0 & Microsoft SQL Server

June 25th, 2017 Michael Bell No comments

I’ve been running image hosting sites for a couple of years. Through my trials I discovered a few things. Running the web server AND the sql server off the same box when you are getting a couple of million image hits a day can be trying on your system. The first version of my image hosting site wrote logs as they came in. 1 image hit actually equalled 3 queries to the DB. That was due to a lack of experience in both architecture and ASP.NET.

In July I decided to rewrite my ASP.NET 1.1 in 2.0. I have plenty of ram in my box, and i knew I wanted to do less queries to my database. What I wound up doing was an in-memory datatable that gets a record for each hit. I used the TableNewRow datatable event to check the record count with each insert. Probaboy not the best method… but I went with it. A more preferable way to do it would be to use a Timer object and firing on the Tick event. In any case, once I reach 10k records, I do a “dump” to the database of the in-memory stuff, and then clean my in-memory table.

As for the “dump”… well… the redesign could not have come at a better time. I was able to utilize the new .NET 2.0 SqlBulkCopy class. What this amounted to was a 4 second query every 10 minutes. Compare that to the alternative of doing several inserts a second… and you can start to see the advantage of in the in-memory/SqlBulkCopy dump technique.

After I released my new version of my image hosting site, I found out REAL fast that there were some problems related to sharing in-memory datatables that are accessed (read, write) constantly (writes 15-20 times a second).

It took me quite a bit of trial and error to figure out how to get it stablized. The server I was working on had dual xeon processors with hyper-threading enabled. What I found was that when this combination was being used, and I was logging hits to an in-memory datatable 15-20 times a second, different threads were trying to log to this table at the same time, causing all hell to break loose.

The fix – briefly lock the table during writes:
lock (MemoryTables.HitList)
{
    MemoryTables.HitList.Rows.Add(row);
}

The dump/rebuild procedure also requires a lock, but it’s very brief:
using (SqlConnection sourceConnection = new SqlConnection(_ConnectionString))
            {
                sourceConnection.Open();

                using (SqlBulkCopy copy = new SqlBulkCopy(sourceConnection))
                {
                    #region Dump and clear hit list
                    copy.DestinationTableName = “FileHits”;
                    lock (_HitList) // Place a lock on the table so incoming hits won’t interupt our dump or our clear
                    {
                        copy.WriteToServer(_HitList);

                        try
                        {
                            if (!(EventLog.SourceExists(SourceName)))
                            {
                                EventLog.CreateEventSource(SourceName, LogName);
                            }

                            // Insert into Event Log so we know logging is taking place as expected;
                            EventLog MyLog = new EventLog();
                            MyLog.Source = SourceName;
                            MyLog.WriteEntry(“Hit data has been dumped. HitList Records: ” + _HitList.Rows.Count, EventLogEntryType.Information);
                        }
                        catch (Exception ex)
                        {
                            throw;
                        }
                        finally
                        {
                            _HitList.Clear();
                        }
                    }
                    #endregion
                }
            }

I half-expected the locking to cause a delay problem in my logging abilities, but I’ve noticed no bottlenecks at all, and this method has been operating trouble free for about a month now.

Categories: ASP.NET, Whatever, c# Tags: