| Chris Skardon 的个人资料Chris Skardon日志列表 | 帮助 |
|
|
2007年6月 Generic Parameterized ThreadsI do quite a bit of multi-threading at the moment, which a long with all the inherent problems (concurrency, complexity etc) makes for some very interesting work. With .NET 2.0 we were gifted with the ParameterizedThreadStart delegate for us to use, which saved a lot of work-arounds involving member variables (and in one case - an intricate queuing system). One thing still puzzles me though - why didn't Microsoft didn't make the ParameterizedThreadStart generic, instead of taking just an object as an argument. The ParameterizedThreadStart delegate is defined as so: public delegate void ParameterizedThreadStart(object obj); This is used when you want to create a new thread and pass an argument to it, (in itself, a big step up from the .NET 1.1 days, when all we had was 'ThreadStart'). The problem is, this now adds an element of un-compile-time-safety to the code, I can pass anything, and will only know about it at run-time. I guess the ideal solution to this from my point of view would be something like: public delegate void ParameterizedThreadStart<T>(T arg); Which would allow me to then call the method I want to start on a new thread type-safely. So, lets start back at the beginning, how do we use the current ParameterizedThreadStart? I have the following method that I want to run in a new thread: private void Inty(int anInt) It's a very simple method, that writes out a message from a for loop, and sleeps for a set time. For me to use this with the current ParameterizedThreadStart I would do this: Thread t = new Thread(new ParameterizedThreadStart(Inty)); Which also requires a change to the 'Inty' method: private void Inty(object obj) Which means I lose all my typesafety, as I can now call my thread such: t.Start("HULLO!"); All valid compile-wise, not good at run-time, as a consequence, I should add some validity checks into 'Inty'. But I just would rather not have to do this. This brought me to write a wrapper for the Thread class, I called it 'Thread' (but in a different namespace), so the code would look the same; First I needed a generic ParameterizedThreadStart delegate: public delegate void ParameterizedThreadStart<T>(T argument); Now I've got that, it's time to create a wrapper, we can't extend System.Threading.Thread as it's a sealed class, so wrapping is our lot. The idea is that I want to be able to create my new thread, and then call 'Start' on it just as a normal thread. My solution is below;
public class Thread<T> I wrap a System.Threading.Thread which I construct and initialise in the constructor. The ParameterizedThreadStart<> which I pass in to the constructor I store as a member variable, ready to be run in the private 'Run' method. The Run method is a match to a standard ParameterizedThreadStart delegate, and performs a cast to the correct type. This cast is safe, as the whole class is made 'generic'. So, to use the new Thread class: Thread<int> t = new Thread<int>(new ParameterizedThreadStart<int>(Inty)); I don't have to make any changes to 'Inty' which is nice, and the compiler will complain if I try to call 'start' with any value other than an int. Equally, if I try to set up the ParameterizedThreadStart<> with anything other than an int the compiler will complain. The only thing I don't really like is the way I have to put 'int' 3 times in that constructing row, I would prefer something like: Thread t = new Thread(new ParameterizedThreadStart<int>(Inty)); but, for type safety I can live with it. 2007年6月 That towel trick...Hrumph! Not effective in my case... The ol' XBox is packed up and ready for shipping to MS' base in the UK. More weeks wait for Forza! 2007年6月 XBox 360 Red Lights of Death...So, here we are, my second xbox 360 has died now, though this time (due to the support line being closed) I perused the masses of online stuff about it and came across a 'Towel' trick - well, to be honest, my girlfriend remembered reading an article in the Guardian. As a result I googled for 'PacoDG towel' and found many-a-page, but in particular an entry by PacoDG on XBox 360 Rally. Currently the xbox is under the towels, so to speak - 30 seconds to go... 2007年6月 First Laptop post!Huzzah! For the first time ever I finally own a laptop! A Sony VAIO VGN-C290, a nice dual core pc ready for my development trials! Hopefully I'll be able to get a lot more stuff done now and write to this blog more, though we'll have to see how that pans out :) 2007年6月 Synchronizing with external changes...Has anyone else seen this message? It appears when go back to my Visual Studio instance containing my (admittedly too large) solution of 170 odd projects (or maybe it's not too large??). The mouse cursor goes into 'busy' mode and I basically can't do anything with visual studio (it goes into 'Not Responding' mode - hence the pale look of the screen shot). I use Sourcegear Vault as my source provider, and also run 'Resharper 2.5' and the SQL 2005 addins in this instance. It's really frustrating, and I haven't seen anything online about this, i.e. I have yet to find anyone else who has discussed it. A couple of my colleagues here do suffer from the same problem, so at least I know it's not isolated to me. Anyone else suffer from this pain? TypeLoadExceptionsOccasionally we get TypeLoadExceptions from .NET code, you can try all manner of programs to try to figure out what the problem is - 'Dependency Walker' is always a good start - but I would recommend before even going down that route -
Always, and I mean always clean the solution (right-click -> clean) and then rebuild if you get a TypeLoadException. This will rule out a large number of problems. Clearly this isn't the only way to get this exception, but it's a good thing to check first. |
|
|