Sync two iTunes libraries

October 11th, 2008

I have two Macs, and I use iTunes on both of them. My music library is managed on my MacBook, but I want access to all of the music on my Mac Pro at home without having to stream it. What’s the easiest way to keep these synchronized? We’re dealing with a Unix, so rsync comes to the rescue:

  1. Please back up your music, in case you get the hosts swapped or something. Tar it up or something:
    tar -zcvf myMusic.tar.gz Music
  2. Make sure one computer is available to the other via SSH by enabling “Remote Login” under System Preferences/Sharing. Grab a terminal and test this:
    ssh userid@hostNameOrIPAddress
  3. Also in the terminal, in your home directory, try a test run of rsync. I am transferring files from my laptop to my desktop, from a terminal on the desktop, so the command is:
    rsync --archive --verbose --rsh=ssh --progress
        --log-file=anyNameYouLike.log --dry-run
        my-macbook.local:Music/iTunes .
  4. Add additional -v flags to get more verbose output. Run until you feel comfortable. Take off the --dry-run and sit back.
  5. Lastly, go select “File/Add to Library…” in iTunes and select your Music/iTunes directory. It’ll churn through the files and update its local database.

C# tip: Touching brain with reflection

September 28th, 2008

In the interest of speed, I’ll start with a list of truths I won’t be discussing at length:

  1. Some day you will need to address a problem in someone else’s libraries without the luxury of patching and recompiling their code.
  2. Most people know .NET reflection allows you to interact with types you didn’t have access to at compile time. It also allows you to interact with types you don’t have permission to directly address in code (internal classes, private members, etc.).
  3. .NET Reflector is an essential tool for any C# developer who uses someone else’s API. Which is everybody.

Using reflection to read members and invoke methods is easy:

  1. Get an instance of System.Type from your object. All objects have a GetType() method.
  2. Call Type.InvokeMember(), passing in the instance you’re wanting to manipulate as well as the name of the member and access flags.

Real-world

The XNA framework is a delightful graphics and games programming API by Microsoft, which is free (as in beer) but not open-sourced, and is officially unsupported. I play a bit with XNA and recently came across a serious performance killer in XNA 2.0 (which I’ve been assured is fixed in 3.0 final; forum post here and bug report here). Basically, there is a leaky dictionary embedded two internal classes deep that never gets cleaned up, framerate goes poop in a little while if you’re loading and unloading content like crazy.

So, inside the public GraphicsDevice class, there is an instance of an internal DeviceResourceManager, and inside this is the collection of internal ResourceData structs which never gets cleaned up. Once the content that’s being tracked has been disposed, its ResourceData instance can go away, so we’re going to periodically poke into this collection and flush items that are slowing down access to the collection.

In our code, we have easy access to the public GraphicsDevice. So, let’s get access to an instance of the internal DeviceResourceManager inside of it, which is a private instance named “pResourceManager”:

Type graphicsDeviceType = this.GraphicsDevice.GetType();
object deviceResourceMgrInst =
    graphicsDeviceType.InvokeMember("pResourceManager",
        BindingFlags.NonPublic | BindingFlags.GetField |
            BindingFlags.Instance,
        null,
        this.GraphicsDevice, // the instance we're manipulating
        null);

So, we have access to a private instance of DeviceResourceManager. Now, we go inside it in the same way to get the private collection:

Type deviceResourceMgrType = deviceResourceMgrInst.GetType();
System.Collections.IDictionary resourceDataDictionaryInst =
    deviceResourceMgrType.InvokeMember("pResourceData",
        BindingFlags.NonPublic | BindingFlags.GetField |
            BindingFlags.Instance,
        null,
        deviceResourceMgrInst,
        null) as System.Collections.IDictionary;

Inside the class there is a sync object for locking as we address the dictionary, but now we know how to get access to that and use it. Then, we can iterate over the objects in our dictionary and remove the ones that are no longer in use.

That’s all the magic. Use this sparingly, as the performance of addressing objects via reflection is horrendous, and it’s always dangerous to subvert API access declarations. However, it might be just the thing that saves you in a pinch.

For the curious, the continued code for the XNA 2.0 leak work-around:
Read the rest of this entry »

Davidson Half-marathon

September 25th, 2008


All out at the Davidson half-marathon finish
(thanks to Jeri for picture)

Fun race last weekend in Davidson. Most of Crazy Legs showed up and we even got a few age group awards. I was 13th overall with a 1:25:35, good for an age-group second in my first race in the 35-39 group (congrats to fellow CL Paul Gonzalez for getting first about a minute ahead; I was no match for him in on the hills).

C# tip: Dependency Injection on the cheap

September 18th, 2008

I want to keep this post short, so I won’t go into why you should design your code around interfaces, or why injecting dependencies at runtime is such a good idea. Rather, if you’re using .NET and want to quickly use Dependency Injection in your design, but are hesitant to adopt yet another framework (like Spring.NET, which I heartily recommend) for whatever reason, look to System.Activator.

In the way I usually use Activator, you need:

  1. The path to the assembly containing your implementation. The magic here is that you don’t need this referenced anywhere in the original application (you know, Dependency Injection and all).
  2. The name of the implementation class you want to load. I’m actually going to traverse all of the types in the injected assembly, which isn’t necessarily the most secure or efficient way to do things, but it is convenient and works well.

Namespaces used:

  1. System.Activator, to create the instance from a loaded assembly
  2. System.IO.FileInfo, to conveniently get the full path to the assembly you want to load
  3. System.Reflection.Assembly, to load your assembly (inject the dependency) into the current app domain

Some code:


  IPluggableDependency pluggableInstance = null;

  // Load the injected assembly with its absolute path
  FileInfo assemblyFile = new FileInfo("PluggableStuff.dll");
  Assembly assembly = Assembly.LoadFile(assemblyFile.FullName);

  // Find the matching Type you're wanting to instantiate
  foreach (Type type in assembly.GetTypes())
  {
    if (type.FullName == "PluggableStuff.ClassName")
    {
      // Create an instance of your implementation,
      // cast as an interface
      pluggableInstance = Activator.CreateInstance(type)
        as IPluggableDependency;
    }
  }

Now, as I said before, look into using a lean, established, flexible, robust DI framework like Spring. However, if that’s not an option for whatever reason, you can still build your apps around a nice DI pattern. Future migration to Spring will be a snap.

Blue Ridge Relay 2008

September 13th, 2008

Last weekend was the Blue Ridge Relay, which is 209 miles and 24+ hours of sick quad- and hamstring-bashing. Our Crazy Legs team showed up with a full twelve-person roster, and pulled out an impressive seventh-place (out of 75+ teams) in 26:45.


The view from “Goat Hill”, somewhere in the Blue Ridge Mountains

I ran position eight, with a first leg of 4.5 miles (moderately hilly), which I tried to run at my 5k pace. My overnight leg was 8 miles (nightmare dark mountain up, up, up, then screaming down), during which I experienced repeated heartburn worse than any college beer and wings episode. A sunburn and a general lack of sleep during the preceding week almost got the better of me before the night run, but passing a bunch of people delivered enough oh-so-lovely adrenaline to keep the feet turning over.


Mike “Goat” Smith cranking Goat Hill

At the top of Goat Hill, I got the hand-off for my last leg, which was 9.4 miles downhill with over 2000 feet of descent. I cranked it as best I could, averaging sub-6s. My quads were destroyed for a week.

Prior to downhill bash (thanks Cheryl for the pic)


Coach Tino rounding the corner for the finish

The finish was in downtown Asheville. Luckily, the downtown Y allowed participants to shower afterward, so everyone was able to survive the ride back to Charlotte.

Two vans’ worth of Crazy Legs

I’d go on about how fun the team was, but it would mostly be “you had to be there” stuff. Which, of course, is what makes these sorts of things worthwhile. I fully expect to run this event again, probably with much the same crew, and preferably as an ultra team (running more, but avoiding all the waiting around). Also, I’ll get more than three hours of sleep the night before the race next time.

I have a bunch more pictures at this link, and Mike’s Flickr archive is at this link.

McMullen tempo, speedwork, shoes

June 14th, 2008

Started out the new running week (running weeks start in Saturday) with McMullen Creek from 51 all the way to Rea (including the steeplechase construction portion at Johnston). PM was up for a 6:30am start, which was a good thing since the lot was already starting to get busy. DJ showed up and seems ready to resume his Boston quest this year, and PM’s friend R joined us for the first time, and according to PM was there specifically to “kick my ass”; good thing I brought my heart rate monitor for the first time in over a year!

First six out were mild 8:15-ish miles, and I stuck a solid 120bpm all the way out. R and I took off on the way back, intending to run about a five-minute negative split, but we ended up running mid-to-low 6’s (I think) for 4.5 miles; all I’m sure of is that I was at 140bpm for the first two tempo miles, 150 for the third, and then popped 160 over the last mile. He seemed to have plenty of speed left, but I was pushing all out. Awesome getting to chase, which is exactly what I need to get some speed for the Fall. Nobody human runs 2:50 marathons at a 120 heart rate, after all.

Plus, R is on our Blue Ridge Relay team, which means I won’t be the fastest on the team. Sweet! I’ll still happily take spot 2, which is going to bring a new meaning to the name “Crazy Legs”.

In other running news, speedwork on the track has gone well for the past two weeks, though I might finally puke the next time we do 10×400m in 100F temp. Asics finally released the new rev for my favorite racing shoe, the Gel-Speedstar 3, and I have a pair on order. I’ve been doing my speedwork in some new two-models-old DS Trainers I pulled out of the closet and might try the new ones if I don’t love the Speedstar 3 like I did the 2.

Leica M8 review by a real photojournalist

June 13th, 2008

Michael Kamber is a war photojournalist and Leica fan currently operating in Iraq, and in this article he discusses his real-world experiences with the Leica M8. The article is scathing, to put it bluntly. Most interesting to me were not the photographic problems with the camera (absolutely wild fluxuations in color balance, for example) but some very basic usability flaws that rendered the camera unusable for Kamber. In a statement that sounds so familiar to me, he questions whether Leica performed any real-world testing of the camera before shipping. And this guy’s not just being picky.

Originally linked from Luminous Landscape.

Kate Portrait

May 31st, 2008

I love this portrait my sister is doing of my niece. She says it’s a work-in-progress, though I’m in favor of her keeping it in its current state.

img_5279-450.png

I can’t wait to see the companion portrait of my nephew. She paints from photographs, so I’m hoping I can provide a similar portrait of him.

Boston 2008

May 21st, 2008

I’m not sure exactly why I’ve waited a month to write about Boston. Perhaps it was my almost complete lack of photo-taking. More likely, it’s the feeling that I had finally completed a major undertaking, which leaves me exhausted and satisfied for about a week, then the elation turns into nervousness as I realize that I need another goal. New goals are scary, especially considering I had five years to get comfortable with this one.

To put it simply, the Boston Marathon is the best marathon in the entire world, in practically every way. It lives up to every expectation, from the talent level of the field, the difficulty of the rolling course, to the crazy pre-race expo and festivities, to the absolutely mind-blowing crowd support.

The course is every bit as hard as people say, with a quad-crushing downhill trend for the first half, and then crushing uphills for about six miles until 22. I was a bit out of shape for a fast attempt, but I still went out a little fast, loving the opportunity to flow along with huge packs of runners my speed or faster. I honestly got a tiny bit discouraged around half-way, as I’m not accustomed to being continuously passed by entire packs of people, and this trend didn’t let up for the entire race. But even that was incredible, running in a crowd for an entire marathon.

boston2008_450.pngUncomfortably rounding one of the last corners

I’ve never seen crowd support anything like this. Honestly I wonder why so many people turn out, as they are out in decent numbers for the entire course, and in huge crowds through the towns. Children were hanging out of trees, people were barbequeing, college kids were insane. I had heard the stories of the Wellesley girls, but nothing could have prepared me for what sounded like a Beatles concert a half-mile away. I’d go back just for that.

Unfortunately I didn’t quite have the legs I had in Portland or Myrtle, and the weather turned out to be a bit hot and sunny for me, so the hills and sun took their toll on me. No mushroom clould, but running sub-3 was definitely out of the question, so I managed to hold on for a Boston-qualifying 3:13 (Note: I’ll be 35 next year, so I get five minutes, and yes, I was already qualified for ‘09). Unless my dad qualifies for ‘09 (he will definitely be there for ‘10; more on that later), I’m going to try to kill this course next year. Revenge on those hills will be sweet.

pic-0002-edit.pngPossibly the perfect restaurant? Must try it in ‘09

For the entire weekend there are runners everywhere, and you can tell they’re serious runners. Everyone wears bragging gear from previous races, or they’re already wearing a wind jacket for the current race. Thousands and thousands of people, all excited to be there. If you are a runner, really a runner, you must do Boston at least once. It’s not just the reputation, it’s a religious experience. And if you aren’t a runner, I don’t know how you could experience the Boston weekend and not be one by the end of it. Just ask Jeri, Susi, or either of the Pauls.

Happy sandboxes and svn switch

May 8th, 2008

I encourage everyone I work with to keep all of their development code in a source repository, even one-off dead-end prototype code they’re not going to check back into a main development tree. If you know you’re going to do destabilizing work, of course you’ll create a sandbox branch from the development branch and then do your work; we all know this. So, what happens if you inadvertently end up with a dead-end prototype in your working source checkout, and you didn’t have the foresight to start with a branch? It’s easy to make it as if you had.

Disclaimer: Of course, if this all fails you could lose a lot of work, so you might want to generate a quick diff or backup just in case. Just be careful.

  1. Create a development branch in our repository on the server. We are using Windows and TortoiseSVN, and our working code is from the branch at svn://svnserver/MyProject/Trunk at revision 1942. So, we use the Repo-browser in TortoiseSVN to find Trunk, select revision 1942 from the upper right-hand corner of the dialog, and then select “Copy to…” with a new location at svn://svnserver/MyProject/Sandboxes/bojordan/DeadEndPrototype. We now have a new branch, but our working code still belongs to Trunk.
  2. Right-click on my top-level checkout directory, select “Switch” from the TortoiseSVN options, and select the new branch in the “To URL:”. We know HEAD is fine, as we just created the new branch.
  3. Now, the next time we commit our code, we’ll check it back into the new branch. Glee!

Just remember: No more stale development tree archives on your development machines means cleaner, uncluttered living, and might get you one step closer to a 16 minute 5k. Or, maybe not, but you’ll still be happier.

Scraping together Boston training

April 7th, 2008

I have my first Boston Marathon on April 21, and I’m not even remotely ready. I take some comfort in knowing Boston is more a reward than another proving ground, but I still want to give it a tough effort and I’m simply not ready. I ran my marathon PR almost completely solo at Myrtle Beach, and there are thousands of runners my speed or faster at Boston to push me. However, considering my low recent mileage, lack of speedwork, and an inconvenient extra five or so pounds, I should be very happy with a 3:10 (over ten minutes slower).

Honestly, I wish my Boston time didn’t matter to me, but I know myself better than to think I can completely coast it. I can only hope I have enough training base to survive the adrenaline rush I’m going to feel for the first 18 miles. Here’s to going until the wheels fall off! Watch for the mushroom cloud!

Upcoming races

March 1st, 2008

I don’t have major running plans solidified for the rest of this year, other than the obvious highlight that is my first Boston Marathon on April 21. I am looking forward to running a number of half marathons this year, and was expecting to run the Corporate Cup again but will miss it due to a snowboarding trip. Racefest at SouthPark is only a little more than a week before Boston, so I question whether a hard effort there would be wise.

My dilemma? I was hoping to have a NYC qualifying time for guaranteed entry before the May 1 deadline. I’m definitely capable of the 1:23 qualifying time for the half marathon, but I don’t want to jeopardize Boston. The marathon time of 2:55 would be highly ambitious at Boston, but I may consider attempting it if my training goes well. I probably won’t have another half marathon chance before the end of the month, assuming I could even muster the energy.

I want to pick up some speed over the summer, which usually means shorter, more frequent races. I have no idea what’s available in the summer, though Tim’s Ramble Tail Half Marathon at Uwharrie on May 17 is likely.

Returning to Grandfather (July 12) and getting my revenge on San Fran (August 3) would be enormous fun, though this might be prime speed-building time.

Later in the year I’ve committed to running a hard-core leg for Coach Tino at the Blue Ridge Relay on September 5 and 6, and then we have the Crazy-MFn-Legs October Classic two-day expedition (two marathons, one weekend). No time records will be set at either of those, though balls-of-steel bragging rights will be significant.

I would like at least one fast full marathon attempt in the Fall. NYC on Nov 2? Chicago on Oct 12? Portland on Oct 5?

Crowders fun (and a record bonk)

March 1st, 2008

Late last week Mike Smith pointed me toward a Sunday morning Crowders Mountain meet-up on the Native Trail Gods list, organized by Tim Long. I’m always a sucker for runs at Crowders, and the thought of a group run on my favorite local trail was too much to resist. Nevermind the soreness I felt through the week after Myrtle Beach, or the difficulty I had on my Saturday 15 miler. Fun to be had.

Greg, Shashi, and Tim showed up; Tim placed sixth overall at Uwharrie in the 40-miler, so I expected to be left behind fairly quickly. However, everybody’s pace was moderate and I was able to hang with the crew all the way up the fire road, feeling stronger the farther up the mountain I got. After such a strong climb, picking up the pace for the entire white trail out and back was a big thrill. Little did I know the confidence I was gaining was due to my body blatantly lying to me, but it was amazing fun while it lasted.

Read the rest of this entry »

Myrtle Beach 2008

February 24th, 2008

We had a nice crew going to Myrtle Beach this year. The two Pauls were shooting to push Dougherty below his 3:16 needed for Boston, Susi was pacing Jeri in her first race back from her ankle injury, and I was finally trying to break 3 hours.

Jeri and Susi ran a comfortable half, Jeri’s injury thankfully a thing of the past. Being the great supporters they are, I could hear them yelling as I finished right on target in 2:57:40 (top 20!). The last six miles were brutal, the long straightaways of this race a terrible mental test.

Bo finishing

In maximum dramatic form, Dougherty finished with three seconds to spare (3:15:56), with Martino not far behind in a season-best 3:19:37.

pic_0205_450.png

We all earned our post-race massages (great free massage tent), and I even had my first beer of 2008.

Beer tent

I’m not very fond of Myrtle Beach itself, and the race is too straight and flat to be enjoyable to me, but the crowd was great and the whole atmosphere was nice for a mid-sized race.

Uwharrie 2008

February 10th, 2008

I had a wonderful time at the Uwharrie Mountain Run last weekend. The race is very well organized, with good coordination at the start and finish and great support along the course. Very highly recommended.


Showing off 20-miler finisher pottery

I ran the 20 miler as my final long run before a fast attempt at Myrtle Beach next weekend, and was able to avoid any major injuries despite the tricky footing (wet feet, minor blisters, and very sore climbing muscles don’t count). While I tried to remain very conservative and not race (I started mid-pack and cautiously stayed behind traffic for most of the first 8 miles), I was happy I ran every hill except the first. I still finished in 3:28 and some change, good enough for 18th overall. I want to return next year and race it.

Susi deserves congratulations; she finished a very respectable 18th female in her first long trail race. Jeri, out with a big ankle sprain, was great to have there in support.

More photos behind the link

Regarding my running log

February 3rd, 2008

One of my intentions for 2008 was to keep a more diligent log of my exercise. So far, I’m succeeding, and it’s already helping. I suspect most readers of this don’t much care about the daily details of training, so I’ve moved the updates to pages that won’t spill over into the blog. January is here, February here. Feed subscribers rejoice, all three of you.

Why log training activity? This may sound crazy, but my mental window of focus is only a few days wide, and glancing at the past few weeks of training work helps a little in regaining confidence. When I’m not having any trouble with focus or motivation (not-coincidentally, this is usually when I’m mostly group training, but that’s worthy of its own discussion) a training log is little more than a bragging point, and can help a little with a final psyche-up for a big race effort. A daily log is more useful, however, when I’m almost completely distracted, and daily motivation is at a low. Like right now. My past few weeks have been very light, with my ability to get up and motivated in the morning very difficult, due to a mix of some late nights I’ve been putting in and a bit of injury. Due to weekend long runs I’ve still kept overall mileage up around 40 or so, but I don’t feel like I’m doing anything. Why not? I honestly can’t remember what I did just last week unless I write it down, and I get depressed very quickly, panicked that my training base is slipping away.

Are you having trouble staying motivated after setting yet another yearly goal of losing some weight, getting in shape, or just sticking to a plan? Maybe a secret to accomplishing these goals is keeping daily logs.

It’s Chrimmistime!

January 25th, 2008

This week has been a devastating one for AAPL stock, but undaunted by financial realities I am now awaiting the arrival of a new Mac Pro workstation. Seems like forever ago I began my wait for this hardware refresh so I could replace my aging PowerBook 17. Minorly awesome were upgrade prices for Photoshop and Logic that were less than devastating. Unfortunately playtime is postponed until next month, delays resulting from inclusion of the sweet Nvidia 8800GT graphics. The new apartment heater will be installed as late as the end of February.

Swiftboating Obama

January 22nd, 2008

The following is a letter from John Kerry, regarding the many smear emails circulating about Barack Obama. I post this not only because I’m backing the same candidate, but because I’ve also been forwarded some of the same mails from, I believe, well-meaning people. Whatever your political views, do what you can to help end what is no more than hate-mongering. I don’t require you agree with my politics, but I do demand that you argue with the truth.

I support Barack Obama because he doesn’t seek to perfect the politics of Swiftboating — he seeks to end it.

This is personal for me, and for a whole lot of Americans who lived through the 2004 election.

As a veteran, it disgusts me that the Swift Boats we loved while we were in uniform on the Mekong Delta have been rendered, in Karl Rove’s twisted politics, an ugly verb meaning to lie about someone’s character just to win an election. But as someone who cares about winning this election and changing the country I love, I know it’s not enough to complain about a past we can’t change when our challenge is to win the future — which is why we must stop the Swiftboating, stop the push-polling, stop the front groups, and stop the email chain smears.

The truth matters, but how you fight the lies matters even more. We must be determined never again to lose any election to a lie.

This year, the attacks are already starting. Some of you may have heard about the disgusting lies about Barack Obama that are being circulated by email. These attacks smear Barack’s Christian faith and deep patriotism, and they distort his record of more than two decades of public service. They are nothing short of “Swiftboat” style anonymous attacks.

These are the same tactics the right has used again and again, and as we’ve learned, these attacks, no matter how bogus, can spread and take root if they go unchecked.

But not this time — we’re fighting back.

And when I say “we,” I mean that literally. I know Barack is committed to fighting every smear every time. He’ll fight hard and stand up for the truth. But he can’t do it alone.

We need you to email the truth to your address books. Print it out and post it at work. Talk to your neighbors. Call your local radio station. Write a letter to the editor. If lies can be spread virally, let’s prove to the cynics that the truth can be every bit as persuasive as it is powerful.

The Obama campaign has created a place where you can find the truth you’ll need to push back on these smears and a way to spread the truth to all of your address book.

Take action here:

http://my.barackobama.com/factcheckaction

So when your inbox fills up with trash and the emails of smear and fear, find the facts, and help defeat the lies.

Barack Obama is committed to bringing our country together to meet the challenges we face, but he knows that power gives up nothing without a struggle — and to win the chance to change America, we must first defeat the hateful tactics that have been used to tear us apart for too long.

With your help, we can turn the page on an era of small, divisive politics — but only if next time you hear these attacks on Barack, you take action immediately:

http://my.barackobama.com/factcheckaction

The fight is just heating up — we won’t let them steal this election with lies and distortions.

Thank you,

John Kerry

Running progress

January 19th, 2008

Readers of this may find it hard to believe, but before this morning I had not run since last Sunday. This was mostly due to a sore ankle I was allowing to heal, but later in the week laziness simply got the best of me. I paid for this activity on the 22 miler with Martino and Dougherty this morning; even though most of my discomfort was due to some stomach cramps that started around mile 14, my calf muscles got crampy and hurt for the last half. I was happy to have a group to fall back on.

Biggest news is that Charlie appears to have separated his shoulder on a ride and won’t be able to do the upcoming Uwharrie race. Dude! I was looking forward to seeing them at the race, even if we were going to be on different races.

Regarding Uwharrie, Jeri, Susi and I visited the northern trail head last Sunday and checked out the top half of the course. The elevation changes were serious, but not nearly as bad as I was fearing. Footing is often sketchy with all the rocks around, but wouldn’t be so bad in the Spring when the leaves are gone. My aforementioned ankle/achilles was very evident toward the end of the run.

So, Uwharrie and Myrtle Beach are coming up, and I’m not yet at 100%. Still, with an easy pace on the trails I think I can still be ready to break 3 hours two weeks later.

C# tip: Formatting currencies

January 16th, 2008

Another simple C# tip I keep forgetting: Need to format a decimal for a specific currency? What about only showing the whole dollar amounts? Use the Decimal.ToString() overload that takes a format string and a CultureInfo instance. Here’s how:


    // CultureInfo is in System.Globalization namespace
    decimal amount = 10m;

    // show British pounds
    Console.WriteLine(amount.ToString("C0", new CultureInfo("en-GB")));

    // show Euros
    Console.WriteLine(amount.ToString("C0", new CultureInfo("fr-FR")));