Caught up on reading

by Administrator 2. January 2006 03:41

Despite various studies indicating the negative effects on employee productivity and especially morale my current client has purchased "Websense" to do detailed internet site blocking and surf-volume reporting.  I wonder how much money it cost them to reduce their employee productivity and job satisfaction in this manner?  Why does this bother people?  I suspect a top reason might be that most websites are not quite as ubiquitous as a phonecall.  Many firms have reviewed phone records for years and too much tele time might get you a stern talking to.  Your manager does not necessarily know what you called your wife 17 times a day about, just that you did.  Visiting websites, though, might give various keys as to your political beliefs, religious affiliations, and various other things someone could hold against you.  One would think that in the Litigious States of America this is knowledge employers would not want.  Now someone can claim they were let go because their manager snooped their internet habits and found out that they were gay, had HIV, was an atheist, voted Democrat, etc.

At any rate I've had to cut everything but MSDN and Fox News out of my daily diet in an effort to stay off of the top daily surfers list.  I typically have other work to do at home and the holidays have not given me more free time.  I finally set down and read/skimmed several hundred articles worth of waiting content.  To my fellow Wisconsin bloggers: I am caught up now.

I will be having a Nerd Lunch late this week to preview my INETA presentation next week. 

Tags:

The xmas spammer

by Administrator 27. December 2005 16:16
I have always had a small amount of spam on this site.  I checked my email on christmas day to discover I had 6000 referral spam instances (I had the blog engine set up to email me) waiting for me.  I will be temporarily turning off all the trackback, pingback, and referral features until I get time to upgrade the engine later this week.

Tags:

Invoking and Delegates

by Administrator 20. December 2005 17:19

As promised, I have some ideas regarding Async code for beginners.  Part one of three.

Compact Framework

The first thing to learn when doing asynchronous programming on the Compact Framework is that it is not as forgiving as the full .NET framework.  Threading things that might be a problem on a Pentium IV will be a problem on a 400mhz XScale.  The first problem you may run into, since its not well documented is Thread priorities.  You may want to give your "worker" threads more CPU time than the UI thread.  While the thread priority method exists on the thread class in the CF it is unofficially unsupported in CF 1.0.  I have tested this on at least 3 different devices with both CE.NET 4.2 and Windows Mobile and any attempt to set a thread priority locks up execution and debugging.

Your UI is running on a thread that processes events and updates UI controls.  In fact the compact framework starts quite a few threads you have no control over, for exampleTCP listeners and such when you execte web services.  Any attempt to access a GUI control's properties from outside this UI thread could cause unexpected behavior, including the program locking up and no longer responding.  Often you can get away with reading a control's properties without locking up, but setting a Label Text property is much more likely to cause a deadlock.  The way you access a control's properties from your worker threads, then, is using Control.Invoke.  The method description for Control.Invoke says:

"Executes the specified delegate on the thread that owns the control's underlying window handle."

That should be fairly straight forward.  There is a Message Pump running.  Every time something happens in GUI code that changes some visual aspect of a control it occurs as the Message Pump dispatches messages.  Code you call directly from the UI thread automatically gets executed this way,  Control.Invoke gives you a way to execute some code from within this message pump without exposing the internals to you.  On Compact Framework 1.0 only the version of Control.Invoke that takes a no-arguments Delegate is supported.  In CF 2.0, Control.Invoke (Delegate, object[]) is also supported, which eliminates the need for the following tip:

Since you cannot pass arguments to Control.Invoke in CF 1.0 you may need a way to communicate with your UI controls from a worker thread.  For example, suppose you have a custom sync process running on a worker thread and you want to update a Label each time a table is processed with the name of the next table name.  I would argue that the worker thread having any knowledge of the UI controls is bad, so you need a better means of communicating.  The Mediator/Director pattern from the GOF design patterns book provides a solution.  Consider the following:

On the Worker thread class:

OnPullStart(new PullStartEventArgs("Next Table Name"));

...

public event PullStartEventHandler PullStart;
        protected void OnPullStart(PullStartEventArgs e)
{
  if (this.PullStart != null)
  {
    PullStart(this, e);
  }
}

On the Director we have a method or property we can talk to which keeps the UI control decoupled from other classes:

...
public string SyncMessage
{
get{ return _syncMessage;}
set
{
_syncMessage = value;
_someControl.Invoke( new EventHandhler(_someControl.SyncMessageChanged));
}
}
...

On the GUI control owning the Label, which also kicked off the worker thread, you supply an EventHandler:

public void SyncMessageChanged(object sender, EventArgs e)
{
  _someLabel.Text = Director.Instance.SyncMessage;
}

Note that in some cases you may wish to synchronize access to the value from the Director.  Every application is different.  This is a somewhat simplified example.  In my real applications I typically have a "Context" (Possibly State pattern) object of some kind which keeps State for me, and the Director just fires messages.  There are different techniques to use, but I will offer some tips:

  1. Whenver dealing with updating the UI, always be concious of "What thread is this method being called from?"
  2. In light of #1, be sure ALL code that touches GUI components has come from an invoke method.  Sometimes even Querying a Control's property from outside the UI thread can cause a lockup.
  3. Use Events on a worker thread to signal a significant event that a client class may be interested in.
  4. Do not pass instances of your controls to worker threads so that the worker can call Invoke, use a technique that decouples the worker thread from any classes that might subscribe to the worker class's events.

Modal Mixing

The very excellent OpenNETCF libraries for the .Net compact framework provides some extended functionality for processing windows messages.  Much of this is in the ApplicationEx class, allowing you to run your GUI's main form using ApplicationEx.Run( new MyForm() );.  I have also experienced different GUI lockup situations where different ShowModal() and MessageBox calls are mixed.  If you need to show a modal Form be sure to use the new ApplicationEx.ShowDialog(Form, bool dispose) rather than Form.ShowDialog(); this will ensure the form is blocking the correct message pump.

The next threading article will be a short one discussing a couple of easy performance tricks you can use Threads for in ASP.NET.  In the article after that I will show some other threading techniques.

Tags:

Thinking Async and Optimization

by Administrator 14. December 2005 17:27

.NET Architect, gourmet cook, and all-around good guy Matt Terski confided in me once that the great hurdle in getting peolpe to understand SOA was not teaching them transport protocols and such but getting them to Think Asynchronously.  I have posted before about how the Cage Builder culture in some organizations tells developers to "Never use threads".  This is a barrier to responsive apps, great performance, and adoption of SOA.

For my current client I built another custom data synchronization process for a mobile device.  We are not using Merge Replication for any number of reasons, mostly because of the constraints it puts on your database schema.  This sync process runs over a Sprint Airlink modem mounted on a truck; the speed of the modem is entirely dependent upon the quality of the connection it has at any given time.  Since the trucks could be in the middle of nowhere or surrounded by power lines I'm lucky to get 4k/s on some days.  A normal sync was taking about 3 and a half minutes and I was asked to optimize it.  We are moving to SQL Mobile in Q2 2006 but that doesn't help us today so I sat down to see what I could do to make this faster.

Long story short, I have it to just under one minute now.  They are pleased.

Most of the Performance talk you see going around deals with things like "avoid boxing", "use StringBuilder", "stored procedure", etc.  Those are the last things I look at, the first things are improving the efficiency of data stores and Asynchronous processing. 

Improving the efficiency of your database is a huge topic and one that I am only now becoming more familiar with.  My current sync process is largely based on DateLastChanged fields on various tables, and some of those are large for SQL CE, say 20,000 rows.  Adding an Index on the DateLastChanged fields of some large tables changed the operation from Table Scan to Bookmark seek, and took many seconds off of my times.  There is no execution plan viewer on SQL CE 2 to prove that statement, but the proof is in the performance. 

The larger part of my 300% improvement was "Processing Item A while waiting on Item B to be done". I am going to write three articles as I get time about some very simple Practices I use to keep me honest and reap the benefits of Thinking Asynchronously.  My 3-part intro to threading will consist of:

  1. Control.Invoke practices for the CF and Delegates in ASP.NET
  2. Practices for Work Item constructs
  3. Thread Signaling

Tags:

House Building

by Administrator 28. November 2005 19:47

Do not build with Cade Homes of Milwaukee!

Once upon a time I decided to build a house.  It hasn't been going well, and my builder could care less if they finish my house or if I drop dead tomorrow.  In my industry time and cost overruns happen often, however most Consulting firms suffer from this crazy idea that even when things go wrong and we make mistakes the customer should get good value from us and ultimately be happy not only with the end result of our work but the experience of working with us as well.  Maybe it has something to do with Milwaukee being a small town and people talking to each other...

In the case of my builder they can treat me however they want and still get their money, and they are obviously unconcerned with what unhappy customers say.  The only recourse I have is to encourage everyone who will listen to avoid building with this company.  Based on the rule that "each person tells 10 other people" perhaps some day they will track lagging sales back to that one customer that they made feel unimportant and crazy every chance they got.  Its far more likely that word will get around "Wow that Damon guy holdes grudges I guess" and for that reason I typically keep personal stuff off of this blog.

This post will remain until I get some incredibly intresting (ergo, don't hold your breath) piece of tech to post about.  If you are in the area and considering building a house, I'd be happy to send you copies of my two complaint letters to the Metro Milwaukee Builder's Association nicely summarzing Cade's apathy towards their customers.

Tags:

Object Data Source

by Administrator 26. November 2005 03:42

ObjectDataSource, I hardly knew ye. 

Once I did get to know you, I didn't like you.  You see, when I saw the ObjectDataSource demos I thought "Finally, Microsoft understands me".  I did a couple of quick tests of the designer support and functionality and was pleased with the results.  Tonight I created a "service agent", a class to wrap access to an out of process call, in this case playing around with the Amazon.com affiliate program again.  For operations that require input parameters to the ODS you can often just tie the parameters to a control on your page using markup and with one line of code:

protected void searchBtn_Click(object sender, EventArgs e)
{
  amazonDs.DataBind();
}

gets the results out of the service agent class.  The ODS pulls the parameters our of the configued form fields and away we go.

Then I realized I am still a misunderstood objects maniac lost in a world of DataSet coding.  Once my List<CustomType> is read from my middle tier object it no longer exists.  Anywhere.  I had deluded myself into thinking that things like "SelectedRow" in a GridView would give me something I could cast to my CustomType, that various GridViewEventArg/ObjectDataSourceEventArg.DataItem would give me something I could cast back to my custom type.  Maybe GridView.SelectedRow would contain a set of values I could use to rebuild my entire object...

No, no, no.  I will say for some types of things the ODS is still useful.  As long as you don't mind looking up your objects using a DataKey and/or your model fits in with this a little bit better than mine does I would still prefer this over an SqlDataSource  So unless I find some obscure method that is not presenting itself right now I am back to programming the same way I did in ASP 1.1: Get ArrayList of Objects, put in session to refer to them later, configure <Columns> in Grid control, DataSource, DataBind, etc.

Tags:

Artificial AI

by Administrator 21. November 2005 04:16

No, that's not a typo.

I have long been enamoured of the Amazon.com WebService API and have recently began actually using them in a semi productive fashion.  In the web service developer's newsletter I see this in tonight's release:

"When we think of interfaces between human beings and computers, we usually assume that the human being is the one requesting that a task be completed, and the computer is completing the task and providing the results. What if this process were reversed and a computer program could ask a human being to perform a task and return the results? What if it could coordinate many human beings to perform a task?

Amazon Mechanical Turk provides a web services API for computers to integrate Artificial Artificial Intelligence directly into their processing by making requests of humans. Developers use the Amazon Mechanical Turk web services API to submit tasks to the Amazon Mechanical Turk web site, approve completed tasks, and incorporate the answers into their software applications. To the application, the transaction looks very much like any remote procedure call - the application sends the request, and the service returns the results. In reality, a network of humans fuels this Artificial Artificial Intelligence by coming to the web site, searching for and completing tasks, and receiving payment for their work."

You can read more about it here: http://www.amazon.com/gp/browse.html/ref=aws_gen_nl13amt/104-4070773-8438325?node=15879911

I find this interesting in light of all the captcha and captcha breaking and ideas for better captcha going on.  It seems necessary for irony's sake to now implemented an automated system that can respond to these requests and get it right...

Tags:

Compact Framework V2

by Administrator 15. November 2005 18:03

During the visual studio 2005 beta I did some testing with CF v2 and was very excited by the results.  The tests were done on one of my CE.net 4.2 devices.  I was told by numerous Microsoft people that when the final version came out it would require CE 5 to run, which is a serious kick in the junk.  There are some very serious issues with the CF version 1, most notably working with SQLCE 2.0.  By forcing the CE 5 issue, any future hope for people who don't have the ability to upgrade to CE 5 is crushed.  Did I say it was a hard kick in the throat?  Just to tease me, creating a Smart Device CAB project in VS 2005 shows "OSMin" as 4.00, this is clearly just thrown in to confuse and annoy since OSMin is really 5.0.

On well known compact framework usenet guy Daniel Moth's blog (link is not working for me) he states that there is a chance that a service pack for the Compact Framework v2 will include "runtime only" support for ce.net 4.2;  I would assume this will allow SQL Mobile to run as well.  I would encourage you to go to http://lab.msdn.microsoft.com/productfeedback/ and do a search for compact framework 2 on CE.net 4.2 and vote for it.

Tags:

snippit

by Administrator 14. November 2005 21:03

I did a brown bag demo of some VS 2005 stuff today and found that a construct I use a lot : try/catch/finally is not in the standard code snippets so I set about creating it.  I was somewhat disappointed not to be able to find an interface within visual studio to do this, so I found the code snippet files and copied one of them.  I created a snippet as follows:

<?xml version="1.0" encoding="utf-8" ?>

<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">

<CodeSnippet Format="1.0.0">

<Header>

<Title>trycf</Title>

<Shortcut>trycf</Shortcut>

<Description>Code snippet for try-catch-finally</Description>

<Author>DamonPayne.com</Author>

<SnippetTypes>

<SnippetType>Expansion</SnippetType>

<SnippetType>SurroundsWith</SnippetType>

</SnippetTypes>

</Header>

<Snippet>

<Declarations>

<Literal>

<ID>expression</ID>

<ToolTip>Exception type</ToolTip>

<Default>System.Exception</Default>

</Literal>

</Declarations>

<Code Language="csharp"><![CDATA[

try

{

$selected$

}

catch($expression$)

{

//Handle exception

}

finally

{

$end$

}]]>

</Code>

</Snippet>

</CodeSnippet>

</CodeSnippets>

and saved it in a file called trycf.snippet.  It's fairly easy to follow what to do, if you want to be able to tab among items you create a <Declaration> and then refer to it by its Id tag ala : $mystuff$.  There is a built in $selected$ Declaration in case you use ctrl+k,s to "surround with"

  I thought I might make several of these so I made a folder c:\Projects\code snippets and went to Tools-->Code Snippets Manager to tell visual studio about my new snippet.  Clicking on "Add" let me browse and find my custom directory, however  the behavior in the IDE then changes to the following:

... and I didn't like this, I want to avoid extra keystrokes although I suppose categories might be useful for some people.  I'm trying to use snippets to stave off carpal tunnel here people.  You can highlight the Visual C# category and chose "import" though and it appears in line with the other snippets.

Tags:

Winner

by Administrator 9. November 2005 15:08
At the Wisconsin .NET user's group's Visual Studio/SQL Server 2005 launch even last night I won full copies of Visual Studio 2005 and SQL Server 2005.  Of course I already have these through MSDN and the copies are marked "Not for Resale".  They're valuable so I don't want to just give them away.  I did note that they are not marked "Do not trade this for an XBox or Beer"...

Tags:

About the author

Damon Payne is a Microsoft MVP specializing in Smart Client solution architecture. 

INETA Community Speakers Program

Month List

Page List

flickr photostream