# Thursday, April 05, 2007

Another feature that missed the 2.1 cutoff - we've added a couple things to our existing EventWaitHandle:

A Set() overload:
public bool Set(int data)

A GetData method:
public int GetData()

For simple, fast, and really easy to implement IPC you can just do this:

Process A
EventWaitHandle wh = new EventWaitHandle(false, EventResetMode.AutoReset, "MY_EVENT_NAME");

int myData = 10;
wh.Set(myData);

Process B
EventWaitHandle wh = new EventWaitHandle(false, EventResetMode.AutoReset, "MY_EVENT_NAME");

if (m_eventsHandle.WaitOne())
{
    int myData = m_eventsHandle.GetData();
}

No MessageWindows, no queues - no ugliness at all - and it works with really minimal headless CE systems.

Thursday, April 05, 2007 10:42:43 AM (Central Daylight Time, UTC-05:00)  #     | 

I know, SDF 2.1 has only been out for a day, but we're always working on the code base.  I just wrapped up a namespace that didn't make the 2.1 cutoff: OpenNETCF.WindowsCE.Services.  It allows you to enumerate, start, stop, refresh, load, unload, set the debug mask and register for autostart any service on the device.

Moving forward we're trying to componentize the SDF, so this one is stand-alone with no additional dependencies (not even the core OpenNETCF.dll library)

Here's a screen shot of my test/sample harness:

 

Thursday, April 05, 2007 10:05:41 AM (Central Daylight Time, UTC-05:00)  #     | 
# Friday, March 23, 2007

SDF 2.1 Preview - Get LIT

Ever have a business scenario where you want your application to perform some task on a periodic basis but the period will be very long - maybe days, weeks or even months?  You want it to occur if the device is asleep or aware at the time?  Well we've got a new SDF class that's designed for this: the LargeIntervalTimer (or LIT).

Let's look at a simple scenario.  Let's say I'm writing a custom calendar.  I want to set up a recurring meeting.  Well let's say the first meeting will be tomorrow at the same time as it is now (for simplicity) and then every 7 days after that.  We want the device to do something on that period (presumably make a noise, vibrate or whatever. 

The LIT is specially designed for this type of scenario.  The code to do achieve that scenario would look like this:

// we want the first timer event o happen 1 day from now
m_lit.FirstEventTime = DateTime.Now.AddDays(1);

// after the first event, we want it to fire every 7 days
m_lit.Interval = new TimeSpan(7, 0, 0, 0);

// we want it to be recurring
m_lit.OneShot = false;

// wire up a handler
m_lit.Tick += new EventHandler(LIT_Tick);

// start the timer
m_lit.Enabled = true;

That's it.  No P/Invokes.  No ugly Notifications, threads, events or whatever.  We've swept all that ugliness under the rug for you so all you need to do it implement your app.

Friday, March 23, 2007 2:56:43 PM (Central Standard Time, UTC-06:00)  #     | 
# Thursday, March 08, 2007

And so ends the debate of whether you can time an engine by ear or not.

 

Thursday, March 08, 2007 8:00:38 AM (Central Standard Time, UTC-06:00)  #     | 
# Wednesday, February 28, 2007

I've been writing apps in mostly C# for several years now.  Of course I've also been doing drivers and kernel work in C or C++, and that has only improved my ability to write, debug and understand managed code in ways that pure managed developers will never really get.  Hell, I pretty much believe that if your managed code doesn't require allowing unsafe code then it could probably be done better.

Well for a few months now I've been neck-deep in a C++ application.  It was started using MFC, which tends to give me a rash just by saying the letters, but it was a customer decision not mine.  At any rate, I was doing some work with a RAS class where I needed any number of consumers to be able to be notified of any changes in the RAS dial status (dialing, connecting, authenticating, etc.).

Imagine a C# class for RAS that will expose events for when the dial staus changes.  THe first thing you'd need is a delegate, right?

In C# you'd have this (assuming DialStatus is an enum):

delegate void DialStatusChange(DialStatus dialStatus);

Well the c++ I wrote (without even thinking about C#) looked eerily familiar:

typedef void(*DIAL_STATUS_DELEGATE)(DialStatus newStatus);

In C# you'd use the += or -= operators for adding an event handler to a classes event, so we get spoiled.  In VB, you call AddHandler with the event name and then the address of the handler.  Well my C++ had a private vector of function pointers (which the CF maintains internally):

std::vector <DIAL_STATUS_DELEGATE> ConnectionManager::m_statusCallbackList;

And then I added methods for adding and removing handlers to the class:

 void ConnectionManager::StatusAddHandler(DIAL_STATUS_DELEGATE callback)
 {
   m_statusCallbackList.push_back(callback);
 }
 
 void ConnectionManager::StatusRemoveHandler(DIAL_STATUS_DELEGATE callback)
 {
   std::vector<DIAL_STATUS_DELEGATE>::iterator iterator;
 
   for(iterator = m_statusCallbackList.begin() ; iterator != m_statusCallbackList.end() ; iterator++)
   {
     if((*iterator) == callback)
     {
        m_statusCallbackList.erase(iterator);
        break;
     }
   }
 }

And how about usage?  In C#, our event-exposing class would have a defined event:

 event DialStatusChange OnStatusChange;

and then when we want to raise the event (assume it's multicast) from our app, we'd do something like this:

 if (OnStatusChange != null)
 {
     foreach (DialStatusChange dsc in OnStatusChange.GetInvocationList())
     {
         dsc(newStatus);
     }
 }

Well my C++ didn't need the event declaration, but raising the "event" (which is simply calling a function pointer callback) looked like this:

 std::vector<DIAL_STATUS_DELEGATE>::iterator iterator;
 
 recheck2:
 for(iterator = m_statusCallbackList.begin() ; iterator != m_statusCallbackList.end() ; iterator++)
 {
   if(IsBadCodePtr((FARPROC)(*iterator)))
   {
      // invalid callback found (someone hooked us then died without unhooking)
      m_statusCallbackList.erase(iterator);
      goto recheck2;
   }
      (*iterator)(status);
 }

Now this was just off the top of my head, so maybe there are improvements that could be made, but it kind of surprised me how I'd taken the concepts I really learned in C# and translated them back to my C++ code.  So yes, writing C# can make you a better C++ developer.

Wednesday, February 28, 2007 11:02:32 PM (Central Standard Time, UTC-06:00)  #     | 
# Thursday, February 22, 2007

For all those naysayers who complain that we don't do enough free stuff for the community, here's another contribution:

We're now hosting the latest zlib source for Windows CE and a managed wrapper for it.  Click the bitmap or here for more info.

Thursday, February 22, 2007 10:49:30 AM (Central Standard Time, UTC-06:00)  #     |