How do I simplify my code? - c#

I just finished creating my first major application in C#/Silverlight. In the end the total line count came out to over 12,000 lines of code. Considering this was a rewrite of a php/javascript application I created 2 years that was over 28,000 lines I am actually quite proud of my accomplishment.
After reading many questions and answers here on stackoverflow and other sites online, I followed many posters advice: I created classes, procedures, and such for things that I would have a year ago copied and pasted; I created logic charts to figure out complex functions; making sure there are no crazy hidden characters (used tabs instead of spaces); and a few others things; place comments where necessary (I have lots of comments).
My application consists of 4 tiles laid out horizontally that have user controls loaded into each slice. You can have between one and four slices loaded at anytime. If you have once slice loaded, the slice takes up the entire artboard...if you have 2 loaded, each take up half, 3 a third, 4 a quarter.
Each one of these slices represent (for the sake of this example) a light control. Each slice has 3 slider controls in it. Now when I coded the functionality of the sliders, I used a switch/case statement inside of a public function that would run the command on the specified slice/slider. This made for some duplicate code but I saw no way around it as each slice was named differently. So I would do slice1.my.commands(); slice2.my.commands(); etc.
My question to you is how do I clean up my code even futher? (Sadly I cannot post any of my code). Is there any way to take this repetion out of my code?

What you need is an interface with your friend the Strategy pattern. For example:
public interface ISlice
{
public Slider Slide {get;set;}
}
public class Slice1 : ISlice
{
public Slider Slide { get; set; }
}
public static class SliceSlider
{
public static void DoSomethingCoolWithTheSliceSlide(ISlice slice)
{
slice.Slide.LookitMeIAmLearningDesignPatterns();
}
}

Writing less code shouldn't be your goal. In the end it's all about TCO (Total cost of ownership).
While owning less code can improve the TCO, there is one factor that has a much greater impact for TCO: maintainability. You should write the most maintainable code. Start by reading Robert Martin's Clean Code.
Update:
Also you say “I have lots of comments”. This is a point where you might improve your code. As you will learn from Martin’s book, good code hardly needs any comments. Martin says that “comments are lies” and “should be reserved for technical notes about the code and design.”.
Update 2:
While I'm add it, here are my favorite quotes from Robert Martin's book:
"a class or module should have one, and only one, reason to change [Single Responsibility Principle]" [page 138]
"More than three [method arguments] is very questionable and should be avoided with prejudice." [page 288]
"The First rule of functions is that they should be small. The second rule of functions is that they should be smaller than that." [page 34]
"Functions should hardly ever be 20 lines long" [page 34]
"The statements in a function should all be written at the same level of abstraction" [page 304]
"Comments should be reserved for technical notes about the code and design." [page 286]

I tend to agree with Steven. Writing less code, or fewer lines, is not always the goal. Thinking back to some of the stories of Steve Wozniak he used to make very compact hardware, putting tons of logic into a very small package, but very few people could follow what he did, maintain it, or manufacture it.
That being said, I suggest you get very familiar with Design Patterns. They may not lessen your lines of code but they may make you code easier to write, maintain, and understand. And a lot of times they do reduce the number of lines you have. Here are some resources:
DoFactory Design Patterns Reference
Wikipedia Design Pattern Acticle

Interfaces and abstract classes are a very strong part of the .net platform.
An interface is nothing more than a contract requirement on a class. That is: an interface is a defined set of methods and/or properties that a class implementing that interface must have. An interface is just a contract declaration.
An abstract class is really powerful because you can carry logic 'into' classes that implement that abstract class. But that is a whole other ball game.
Consider:
public interface ISlice
{
bool DoStuff(string someParameter);
}
public class MySpecificSliceOfType : ISlice
{
// this must have a method implementation for the [bool DoStuff(string)] method
public bool DoStuff(string mySpecificParameter)
{
// LOGIC in the Specific class
return(true);
}
}
public class MyOtherSliceOfType : ISlice
{
// this must have a method implementation for the [bool DoStuff(string)] method
public bool DoStuff(string myOtherParameter)
{
// LOGIC in the Other class
return(true);
}
}
Whilst this is a heavily oversimplified example, declaring the Interface implentation of the ISlice interface on both the classes 'MySpecificSliceOfType' and 'MyOtherSliceOfType' means that the requisite DoStuff() method is regardless of which one you have because you can do things like:
bool sliceReturn = ((ISlice)currentSlice).DoStuff(currentStringParameterValue);
This can save you working through in things like:
bool sliceReturn = false;
switch(typeofSlice)
{
case "other" :
sliceReturn = MyOtherSliceOfType.DoStuff(currentStrignParamterValue);
break;
case "specific" :
sliceReturn = MySpecificSliceOfType.DoStuff(currentStrignParamterValue);
break;
}
The point being illustrated here is even stronger when you have > 2 different types.
And interfaces and abstract classes combine nicely with the C# type checking stuff too.
Interfaces are a fundamental in Reflection ... something to be used very sparingly but understodd because it can save so much in specific cases ... and in Serialisation (a.k.a. Serialization) which can really help you fly.

Since you can't really post any of your code, I might as well throw out a random thought. Can you put these slices into an array? If so you might be able to get rid of some of the redundant code by having each of the controls set a variable (I'll call it whichSlice). so the controls all set whichSlice to the proper number 1-4 and then you run a normal switch and call slices[whichSlice].my.commands();

Related

StoryQ BDD, Given or When without a body

I would like to do a very simple test for the Constructor of my class,
[Test]
public void InitLensShadingPluginTest()
{
_lensShadingStory.WithScenario("Init Lens Shading plug-in")
.Given(InitLensShadingPlugin)
.When(Nothing)
.Then(PluginIsCreated)
.Execute();
}
this can be in Given or When it... I think it should be in When() but it doesn't really matter.
private void InitLensShadingPlugin()
{
_plugin = new LSCPlugin(_imagesDatabaseProvider, n_iExternalToolImageViewerControl);
}
Since the Constructor is the one being tested, I do not have anything to do inside the When() statement,
And in Then() I assert about the plugin creation.
private void PluginIsCreated()
{
Assert.NotNull(_plugin);
}
my question is about StoryQ, since I do not want to do anything inside When()
i tried to use When(()=>{}) however this is not supported by storyQ,
this means I need to implement something like
private void Nothing()
{
}
and call When(Nothing)
is there a better practice?
It's strange that StoryQ doesn't support missing steps; your scenario is actually pretty typical of other examples I've used of starting applications, games etc. up:
Given the chess program is running
Then the pieces should be in the starting positions
for instance. So your desire to use a condition followed by an outcome is perfectly valid.
Looking at StoryQ's API, it doesn't look as if it supports these empty steps. You could always make your own method and call both the Given and When steps inside it, returning the operation from the When:
.GivenIStartedWith(InitLensShadingPlugin)
.Then(PluginIsCreated)
If that seems too clunky, I'd do as you suggested and move the Given to a When, initializing the Given with an empty method with a more meaningful name instead:
Given(NothingIsInitializedYet)
.When(InitLensShadingPlugin)
.Then(PluginIsCreated)
Either of these will solve your problem.
However, if all you're testing is a class, rather than an entire application, using StoryQ is probably overkill. The natural-language BDD frameworks like StoryQ, Cucumber, JBehave etc. are intended to help business and development teams collaborate in their exploration of requirements. They incur significant setup and maintenance overhead, so if the audience of your class-level scenarios / examples is technical, there may be an easier way.
For class-level examples of behaviour I would just go with a plain unit testing tool like NUnit or MSpec. I like using NUnit and putting my "Given / When / Then" in comments:
// Given I initialized the lens shading plugin on startup
_plugin = new LSCPlugin(_imagesDatabaseProvider, n_iExternalToolImageViewerControl);
// Then the plugin should have been created
Assert.NotNull(_plugin);
Steps at a class level aren't reused in the same way they are in full-system scenarios, because classes have much smaller, more encapsulated responsibilities; and developers benefit from reading the code rather than having it hidden away in the step definitions.
Your Given/When/Then comments here might still echo scenarios at a higher level, if the class is directly driving the functionality that the user sees.
Normally for full-system scenarios we would derive the steps from conversations with the "3 amigos":
a business representative (PO, SME, someone who has a problem to be solved)
a tester (who spots scenarios we might otherwise miss)
the dev (who's going to solve the problem).
There might be a pair of devs. UI designers can get involved if they want to. Matt Wynne says it's "3 amigos, where 3 is any number between 3 and 7". The best time to have the conversations is right before the devs pick up the work to begin coding it.
However, if you're working on your own, whether it's a toy or a real application, you might benefit just from having imaginary conversations. I use a pixie called Thistle for mine.

Getting lost in the code, does a better way than creating region exists? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I'm using Visual c# 2010 express edition
I have nearly 1500 effective lines of code, and been using regions regularly, but it's getting out of control, how can i better organize or directly show a method, without having to click in the design form?
Edit: i've read about this http://msdn.microsoft.com/en-us/library/jj739835.aspx (Map dependencies) but it's for visual studio 2013, never heard of anything like it
It's part personal preference, but one can use CTRL+M, CTRL+L to collapse/expand everything to keep things a bit more compact.
Or, through the selector (top-right side of the editor window) you can go straight to a method.
Or (again), the good old Go to definition (F12)
I usually use comments if there's a lot of code in a single file and just ctrl-f to whatever I'm looking for or when applicable I break things up into class files
Try not to keep too much in a single file. Regions are great, but it's even better to avoid the need for them. There is a lot of dogma around "maximum number of lines in a file/class", but all you need to know is, if the file starts getting annoying to read, you need to try and split it up :)
ALways try to describe and name your classes by their functionality. For example, you may have a ScientificCalculator class. As you start to add functions, you start to notice groups of related functionality. Once they go beyond say, 2-3 functions, move them out into new classes!
So your ScientificCalculator class may now refer to smaller classes like BasicOperations, TrigonometricOperations, LogarithmicOperations, etc... you get the picture.
There are many advantages to this, including, but not limited to, easily finding your way around your code. Oh, you want to modify the Sine() function? You know exactly where to look - the TrigonometricOperations class! And that's a much more enjoyable experience in the long run.
Do you have 1500 lines of code in your entire project? Or 1500 lines in a single class? Or (much, much worse) in a single method?
1500 lines for a given project isn't so bad, provided that you've logically broken out your dependencies. 1500 for one class is probably way more than you want to manage.
When writing your classes, try to keep in mind what the class is responsible for. Is it doing to much? Are all the methods related to a single responsiblity? Does it mix things like logic and database interaction? Does it mix presentation logic with business logic?
And if it's 1500 lines of code for a single method, well...
Also, keep in mind that everything in this response should be prefaced with "In general" - there are no strictly prescriptive statements anyone can make about your code without actually seeing it, and there are always special cases.
Finally, if refactoring into separate classes seems like a large effort now, keep in mind that it will only become more and more difficult as your project grows in size and complexity.
Here's a tip that is a bit more controversial than others...
I'll assume the code is not directly under your control, say a legacy set of libraries or web site you inherited instead of designed... If this is not the case then there are much better options as already suggested by others (DRY, Encapsulate, Refactor, etc, etc, etc). However one stop-gap measure that has worked for me in the past is to make use of partial classes.
-----SuperBigClass.cs-----
class SuperBigClass {
public void MethodA(){
}
public void MethodB(){
}
public void MethodC(){
}
...
public void MethodZZTop(){
}
}
....can be separated into a couple smaller files....
-----SuperBigClass - Methods A through Z .cs -----
public partial SuperBigClass {
public void MethodA(){
}
...
public void MethodZ(){
}
}
-----SuperBigClass - MethodZZTop.cs -----
public partial SuperBigClass {
public void MethodZZTop(){
}
}
As long as the term partial is applied to the class definition of all class files and all class definitions are in the same namespace this will work just fine. Here's a link for more info: Partial Classes and Methods (C# Programming Guide)
Again... The best approach is to DRY up code, encapsulate, refactor, etc, etc, etc... but sometimes when you hop into a legacy app and you need to restructure the files themselves without making any functional changes, this shortcut (admittedly an unintended use of the partial class syntax) can be helpful for cutting large files up and helping to make sense of things.

C# On extending a large class in favor of readability

I have a large abstract class that handles weapons in my game. Combat cycles through a list of basic functions:
OnBeforeSwing
OnSwing
OnHit || OnMiss
What I have in mind is moving all combat damage-related calculations to another folder that handles just that. Combat damage-related calculations.
I was wondering if it would be correct to do so by making the OnHit method an extension one, or what would be the best approach to accomplish this.
Also. Periodically there are portions of the OnHit code that are modified, the hit damage formula is large because it takes into account a lot of conditions like resistances, transformation spells, item bonuses, special properties and other, similar, game elements.
This ends with a 500 line OnHit function, which kind of horrifies me. Even with region directives it's pretty hard to go through it without getting lost in the maze or even distracting yourself.
If I were to extend weapons with this function instead of just having the OnHit function, I could try to separate the different portions of the attack into other functions.
Then again, maybe I could to that by calling something like CombatSystem.HandleWeaponHit from the OnHit in the weapon class, and not use extension methods. It might be more appropriate.
Basically my question is if leaving it like this is really the best solution, or if I could (should?) move this part of the code into an extension method or a separate helper class that handles the damage model, and whether I should try and split the function into smaller "task" functions to improve readability.
I'm going to go out on a limb and suggest that your engine may not be abstracted enough. Mind you, I'm suggesting this without knowing anything else about your system aside from what you've told me in the OP.
In similar systems that I've designed, there were Actions and Effects. These were base classes. Each specific action (a machine gun attack, a specific spell, and so on) was a class derived from Action. Actions had an list of one or more specific effects that could be applied to Targets. This was achieved using Dependency Injection.
The combat engine didn't do all the math itself. Essentially, it asked the Target to calculate its defense rating, then cycled through all the active Actions and asked them to determine if any of its Effects applied to the Target. If they applied, it asked the Action to apply its relevant Effects to the Target.
Thus, the combat engine is small, and each Effect is very small, and easy to maintain.
If your system is one huge monolithic structure, you might consider a similar architecture.
OnHit should be an event handler, for starters. Any object that is hit should raise a Hit event, and then you can have one or more event handlers associated with that event.
If you cannot split up your current OnHit function into multiple event handlers, you can split it up into a single event handler but refactor it into multiple smaller methods that each perform a specific test or a specific calculation. It will make your code much more readable and maintainable.
IMHO Mike Hofer gives the leads.
The real point is not whether it's a matter of an extension method or not. The real point is that speaking of a single (extension or regular) method is unconceivable for such a complicated bunch of calculations.
Before thinking about the best implementation, you obviously need to rethink the whole thing to identify the best possible dispatch of responsibilities on objects. Each piece of elemental calculation must be done by the object it applies to. Always keep in mind the GRASP design patterns, especially Information Expert, Low Coupling and High Cohesion.
In general, each method in your project should always be a few lines of code long, no more. For each piece of calculation, think of which are all the classes on which this calculation is applicable. Then make this calculation a method of the common base class of them.
If there is no common base class, create a new interface, and make all these classes implement this interface. The interface might have methods or not : it can be used as a simple marker to identify the mentioned classes and make them have something in common.
Then you can build an elemental extension method like in this fake example :
public interface IExploding { int ExplosionRadius { get; } }
public class Grenade : IExploding { public int ExplosionRadius { get { return 30; } } ... }
public class StinkBomb : IExploding { public int ExplosionRadius { get { return 10; } } ... }
public static class Extensions
{
public static int Damages(this IExploding explosingObject)
{
return explosingObject.ExplosionRadius*100;
}
}
This sample is totally cheesy but simply aims to give leads to re-engineer your system in a more abstracted and maintenable way.
Hope this will help you !

Isn't there a point where encapsulation gets ridiculous?

For my software development programming class we were supposed to make a "Feed Manager" type program for RSS feeds. Here is how I handled the implementation of FeedItems.
Nice and simple:
struct FeedItem {
string title;
string description;
string url;
}
I got marked down for that, the "correct" example answer is as follows:
class FeedItem
{
public:
FeedItem(string title, string description, string url);
inline string getTitle() const { return this->title; }
inline string getDescription() const { return this->description; }
inline string getURL() const { return this->url; }
inline void setTitle(string title) { this->title = title; }
inline void setDescription(string description){ this->description = description; }
inline void setURL(string url) { this->url = url; }
private:
string title;
string description;
string url;
};
Now to me, this seems stupid. I honestly can't believe I got marked down, when this does the exact same thing that mine does with a lot more overhead.
It reminds me of how in C# people always do this:
public class Example
{
private int _myint;
public int MyInt
{
get
{
return this._myint;
}
set
{
this._myint = value;
}
}
}
I mean I GET why they do it, maybe later on they want to validate the data in the setter or increment it in the getter. But why don't you people just do THIS UNTIL that situation arises?
public class Example
{
public int MyInt;
}
Sorry this is kind of a rant and not really a question, but the redundancy is maddening to me. Why are getters and setters so loved, when they are unneeded?
It's an issue of "best practice" and style.
You don't ever want to expose your data members directly. You always want to be able to control how they are accessed. I agree, in this instance, it seems a bit ridiculous, but it is intended to teach you that style so you get used to it.
It helps to define a consistent interface for classes. You always know how to get to something --> calling its get method.
Then there's also the reusability issue. Say, down the road, you need to change what happens when somebody accesses a data member. You can do that without forcing clients to recompile code. You can simply change the method in the class and guarantee that the new logic is utilized.
Here's a nice long SO discussion on the subject: Why use getters and setters.
The question you want to ask yourself is "What's going to happen 3 months from now when you realize that FeedItem.url does need to be validated but it's already referenced directly from 287 other classes?"
The main reason to do this before its needed is for versioning.
Fields behave differently than properties, especially when using them as an lvalue (where it's often not allowed, especially in C#). Also, if you need to, later, add property get/set routines, you'll break your API - users of your class will need to rewrite their code to use the new version.
It's much safer to do this up front.
C# 3, btw, makes this easier:
public class Example
{
public int MyInt { get; set; }
}
I absolutely agree with you. But in life you should probably do The Right Thing: in school, it's to get good marks. In your workplace it's to fulfill specs. If you want to be stubborn, then that's fine, but do explain yourself -- cover your bases in comments to minimize the damage you might get.
In your particular example above I can see you might want to validate, say, the URL. Maybe you'd even want to sanitize the title and the description, but either way I think this is the sort of thing you can tell early on in the class design. State your intentions and your rationale in comments. If you don't need validation then you don't need a getter and setter, you're absolutely right.
Simplicity pays, it's a valuable feature. Never do anything religiously.
If something's a simple struct, then yes it's ridiculous because it's just DATA.
This is really just a throwback to the beginning of OOP where people still didn't get the idea of classes at all. There's no reason to have hundreds of get and set methods just in case you might change getId() to be an remote call to the hubble telescope some day.
You really want that functionality at the TOP level, at the bottom it's worthless. IE you would have a complex method that was sent a pure virtual class to work on, guaranteeing it can still work no matter what happens below. Just placing it randomly in every struct is a joke, and it should never be done for a POD.
Maybe both options are a bit wrong, because neither version of the class has any behaviour. It's hard to comment further without more context.
See http://www.pragprog.com/articles/tell-dont-ask
Now lets imagine that your FeedItem class has become wonderfully popular and is being used by projects all over the place. You decide you need (as other answers have suggested) validate the URL that has been provided.
Happy days, you have written a setter for the URL. You edit this, validate the URL and throw an exception if it is invalid. You release your new version of the class and everyone one using it is happy. (Let's ignored checked vs unchecked exceptions to keep this on-track).
Except, then you get a call from an angry developer. They were reading a list of feeditems from a file when their application starts up. And now, if someone makes a little mistake in the configuration file your new exception is thrown and the whole system doesn't start up, just because one frigging feed item was wrong!
You may have kept the method signature the same, but you have changed the semantics of the interface and so it breaks dependant code. Now, you can either take the high-ground and tell them to re-write their program right or you humbly add setURLAndValidate.
Keep in mind that coding "best practices" are often made obsolete by advances in programming languages.
For example, in C# the getter/setter concept has been baked into the language in the form of properties. C# 3.0 made this easier with the introduction of automatic properties, where the compiler automatically generates the getter/setter for you. C# 3.0 also introduced object initializers, which means that in most cases you no longer need to declare constructors which simply initialize properties.
So the canonical C# way to do what you're doing would look like this:
class FeedItem
{
public string Title { get; set; } // automatic properties
public string Description { get; set; }
public string Url { get; set; }
};
And the usage would look like this (using object initializer):
FeedItem fi = new FeedItem() { Title = "Some Title", Description = "Some Description", Url = "Some Url" };
The point is that you should try and learn what the best practice or canonical way of doing things are for the particular language you are using, and not simply copy old habits which no longer make sense.
As a C++ developer I make my members always private simply to be consistent. So I always know that I need to type p.x(), and not p.x.
Also, I usually avoid implementing setter methods. Instead of changing an object I create a new one:
p = Point(p.x(), p.y() + 1);
This preserves encapsulation as well.
There absolutely is a point where encapsulation becomes ridiculous.
The more abstraction that is introduced into code the greater your up-front education, learning-curve cost will be.
Everyone who knows C can debug a horribly written 1000 line function that uses just the basic language C standard library. Not everyone can debug the framework you've invented. Every introduced level encapsulation/abstraction must be weighed against the cost. That's not to say its not worth it, but as always you have to find the optimal balance for your situation.
One of the problems that the software industry faces is the problem of reusable code. Its a big problem. In the hardware world, hardware components are designed once, then the design is reused later when you buy the components and put them together to make new things.
In the software world every time we need a component we design it again and again. Its very wasteful.
Encapsulation was proposed as a technique for ensuring that modules that are created are reusable. That is, there is a clearly defined interface that abstracts the details of the module and make it easier to use that module later. The interface also prevents misuse of the object.
The simple classes that you build in class do not adequately illustrate the need for the well defined interface. Saying "But why don't you people just do THIS UNTIL that situation arises?" will not work in real life. What you are learning in you software engineering course is to engineer software that other programmers will be able to use. Consider that the creators of libraries such as provided by the .net framework and the Java API absolutely require this discipline. If they decided that encapsulation was too much trouble these environments would be almost impossible to work with.
Following these guidelines will result in high quality code in the future. Code that adds value to the field because more than just yourself will benefit from it.
One last point, encapsulation also makes it possible to adequately test a module and be resonably sure that it works. Without encapsulation, testing and verification of your code would be that much more difficult.
Getters/Setters are, of course, good practice but they are tedious to write and, even worse, to read.
How many times have we read a class with half a dozen member variables and accompanying getters/setters, each with the full hog #param/#return HTML encoded, famously useless comment like 'get the value of X', 'set the value of X', 'get the value of Y', 'set the value of Y', 'get the value of Z', 'set the value of Zzzzzzzzzzzzz. thump!
This is a very common question: "But why don't you people just do THIS UNTIL that situation arises?".
The reason is simple: usually it is much cheaper not to fix/retest/redeploy it later, but to do it right the first time.
Old estimates say that maintenance costs are 80%, and much of that maintenance is exactly what you are suggesting: doing the right thing only after someone had a problem. Doing it right the first time allows us to concentrate on more interesting things and to be more productive.
Sloppy coding is usually very unprofitable - your customers are unhappy because the product is unreliable and they are not productive when the are using it. Developers are not happy either - they spend 80% of time doing patches, which is boring. Eventually you can end up losing both customers and good developers.
I agree with you, but it's important to survive the system. While in school, pretend to agree. In other words, being marked down is detrimental to you and it is not worth it to be marked down for your principles, opinions, or values.
Also, while working on a team or at an employer, pretend to agree. Later, start your own business and do it your way. While you try the ways of others, be calmly open-minded toward them -- you may find that these experiences re-shape your views.
Encapsulation is theoretically useful in case the internal implementation ever changes. For example, if the per-object URL became a calculated result rather than a stored value, then the getUrl() encapsulation would continue to work. But I suspect you already have heard this side of it.

Thread Safe Class Library Design

I'm working on a class library and have opted for a route with my design to make implementation and thread safety slightly easier, however I'm wondering if there might be a better approach.
A brief background is that I have a multi-threaded heuristic algorithm within a class library, that once set-up with a scenario should attempt to solve it. However I obviously want it to be thread safe and if someone makes a change to anything while it is solving for that to causes crashes or errors.
The current approach I've got is if I have a class A, then I create a number InternalA instances for each A instance. The InternalA has many of the important properties from the A class, but is internal an inaccessible outside the library.
The downside of this, is that if I wish to extend the decision making logic (or actually let someone do this outside the library) then it means I need to change the code within the InternalA (or provide some sort of delegate function).
Does this sound like the right approach?
It's hard to really say from just that - but I can say that if you can make everything immutable, your life will be a lot easier. Look at how functional languages approach immutable data structures and collections. The less shared mutable data you have, the simple threading will be.
Why Not?
Create generic class, that accepts 2 members class (eg. Lock/Unlock) - so you could provide
Threadsafe impl (implmenetation can use Monitor.Enter/Exit inside)
System-wide safe impl (using Mutex)
Unsafe, but fast (using empty impl).
another way i have had some success with is by using interfaces to achieve functional separation. the cost of this approach is that you end up with some fields 'repeated' because each interface requires total separation from the others fields.
In my case I had 2 threads that need to pass over a set of data that potentially is large and needs as little garbage collection as possible. Ie I only want to pass change information from the first stage to the second. And then have the first process the next work unit.
this was achieved by the use of change buffers to pass changes from one interface to the next.
this allows one thread to work away at one interface, make all its changes and then publish a struct containing the changes that the other interface (thread) needs to apply prior to its work.
by doing this You have a double buffer ... (thread 1 produces a change report whilst thread 2 consumes the last report). If you add more interfaces (and threads) it appears like there are pulses of work moving through the threads.
This was based on my research and I have no doubt that there are better methods available now.
My aim when coming up with this however was to avoid the need for locks in the vast majority of code by designing out race conditions. the other major consideration is performance in garbage collection - which may not be an issue for you.
this way is all good until you need complex interactions between threads ... then you find that you start forcing the layout of your buffer structures for reuse to get around inheritance which in turn has an upkeep overhead.
A little more information on the problem to help...
The heuristic I'm using is to solve TSP like problems. What happens right at the start of each
calculation is that all the aspects that form the problem (sales man/places to visit) are cloned
so they aren't affected across threads.
This means each thread can change data (such as stock left on a sales man etc) as there are a number
of values that change during the calculation as things progress. What I'd quite like to do is allow
the checked such as HasSufficientStock() for a simple example to be override by a developer using the library.
Unforutantely at present however to add further protection across threads and makings some simplier/lightweight
classes I convert them to these internal classes, and these are the things that are actually used and cloned.
For example
class A
{
public double Stock { get; }
// Processing and cloning actually works using these InternalA's
internal InternalA ConvertToInternal() {}
}
internal class InternalA : ICloneable
{
public double Stock { get; set; }
public bool HasSufficientStock() {}
}

Categories