|
Hi,
maybe it's a simple problem for most of you, but I can't find an easy way to quite simple problem, let me describe:
Let's have this code:
<code>public ClassToChange()
{
...
internal List<AnyDataClass> LockAndGetData()
{
Monitor.Enter(cs);
return data;
}
internal Unlock()
{
Monitor.Exit(cs);
}
private object cs = new object();
private List<AnyDataClass> data = new List<AnyDataClass>();
}
public class Editor
{
public Editor(ClassToChange editedObject)
{
this.editedObject = editedObject;
}
public void MyFunctionToChangeData()
{
List<AnyDataClass> data = editedObject.LockAndGetData();
...
editedObject.Unlock();
}
private ClassToChange editedObject;
}
class Program
{
static void Main()
{
Editor ed = new Editor(new ClassToChange());
ed.MyFunctionToChangeData();
}
}</code>
So my aim is to let Editor change the data of ClassToChange in a thread-safe way. But as you can see to call all the List<anydataclass> data = editedObject.LockAndGetData(), then not to forget the editedObject.Unlock() is very boring to write (and not so safe). Do you have any easy solution for this?
Only solution I have, there might be the CS as attribute of ClassToChange and use lock {} in Editor, but I would need an attribute to every data object of ClassToChange, who would check if the cs is locked to make it safe. So that's also not a good way.
Any ideas?
Michal
modified on Tuesday, April 27, 2010 5:16 AM
|
|
|
|
|
You could potentially use Action<T> delegates to do this. Something like this:
public class ClassToChange
{
private object cs = new object();
private List<String> data = new List<String>();
public void LockAndMakeChange(Action<List<String>> changeAction)
{
lock (cs)
{
changeAction(data);
}
}
}
public class Editor
{
private ClassToChange editedObject;
public Editor(ClassToChange editedObject)
{
this.editedObject = editedObject;
}
public void MyFunctionToChangeData()
{
editedObject.LockAndMakeChange((data) =>
{
data.Add("new string");
});
}
}
This would achieve what you are trying to do. It means your editor only has to call LockAndMakeChange and doesn't have to worry about unlocking afterwards because the class handles it after the action has completed, and your lock object remains private (which is good).
However, you need to be careful with this. By allowing external code to run inside an internally private lock you are introducing a great risk of deadlocking. It is having a similar effect to making your locks public (which is bad). If you aren't very careful other code may be able to take advantage of your exposed locking methods to crash or hang your app.
Instead, I would think about having the modification done entirely within the class so no external code runs within the lock. You could have methods like this that just took in the data and did the modification internally:
public void AddNewString(String newString)
{
lock (cs)
{
data.Add(newString);
}
}
public void AddNewString(params String[] newStrings)
{
lock (cs)
{
data.AddRange(newStrings);
}
}
public void AddNewString(IEnumerable<String> newStrings)
{
lock (cs)
{
data.AddRange(newStrings);
}
} Then you would call it like this:
public void MyFunctionToChangeData()
{
editedObject.AddNewString("new");
editedObject.AddNewString("new1", "new2", "new3");
List<String> newStrings = new List<string>();
newStrings.Add("new4");
newStrings.Add("new5");
newStrings.Add("new6");
editedObject.AddNewString(newStrings);
}
This keeps your encapsulation higher and reduces the risk of deadlocking.
Simon
|
|
|
|
|
Thank you Simon, that's definitely interesting solution. But also too much of writing.
I know I should use locks and change data inside the class. And yes, it's possible by simple classes. But in my experience, more complicated classes will get huge like this. E.g. imagine a class, which contains Bezier curve (or e.g . only simple multi-segment line) and you would have to make all the modifications within this class - like rotation, movement, size change ... so I believe sometimes it's better to have different class for every function of some entity. And this is the only problem I have making it good...
I also think this is quite close to MVC pattern. How to implement it in a thread safe way in C# - hm, I don't know...
Not to mention e.g. whole program. To make some central class, which receives all commands from GUI and executes them (meaning just telling some backend what to do) - huge and awful (I ended up with 3500 lines of code for one class in one project ) - I think it's better to let the commands contain function code, but of course the commands need access to data.
Michal
|
|
|
|
|
Hi,
I have following string. And I have to extract "931.3392ms" from the string. This line of string is not delimited by any character. How do I extract it?
8 (26/04/2010 05:58.03) Execute(WQADataRequest, WQA_LOAD_TYPE.Deep) 931.3392ms (1.7/11.4 KB)
|
|
|
|
|
Are they delimited by spaces? Are there always the same number of elements in your string?
If so, you could split[^] it on the space.
I are Troll
|
|
|
|
|
This line of string is not delimited by spaces.Yes,this particular line always contains same number of elements. Is there any efficient method other than split?
|
|
|
|
|
SRKSHOME wrote: This line of string is not delimited by spaces.
You already mentioned that, just checking since there were spaces in the example-string.
SRKSHOME wrote: Yes,this particular line always contains same number of elements.
Split on some other character? Like the "("?
SRKSHOME wrote: Yes,this particular line always contains same number of elements.
But the elements do not always have the same length?
SRKSHOME wrote: Is there any efficient method other than split?
Yup, using regular expressions[^].
I are Troll
|
|
|
|
|
if the string is always fix size you can simply try the Substring method of the String class.
|
|
|
|
|
Try This
string str = "8 (26/04/2010 05:58.03) Execute(WQADataRequest, WQA_LOAD_TYPE.Deep) 931.3392ms (1.7/11.4 KB)";
MessageBox.Show(
(((str.Substring(str.IndexOf(")") + 1)).
Substring((str.Substring(str.IndexOf(")") + 1)).IndexOf(")") + 1)).
Substring(0, ((str.Substring(str.IndexOf(")") + 1)).
Substring((str.Substring(str.IndexOf(")") + 1)).IndexOf(")") + 1)).IndexOf("(")))
);
Rajesh B --> A Poor Workman Blames His Tools <--
|
|
|
|
|
Thanks...This works efficiently.
|
|
|
|
|
Gr8... very smart.
Thanks
Md. Marufuzzaman
I will not say I have failed 1000 times; I will say that I have discovered 1000 ways that can cause failure – Thomas Edison.
|
|
|
|
|
|
I can't disagree more, that is horrible code. It is unreadable, it has 7 calls to IndexOf where you only need 3, and 7 to SubString where you also need just 3.
string a=str.Substring(str.IndexOf(")") + 1);
string b=a.Substring(a.IndexOf(")") + 1);
string c=b.Substring(0, b.IndexOf("("));
The Regex alternatives are pretty simple too, here is one; the result excludes the surrounding spaces:
string d=Regex.Match(str, @"\) ([0-9\.]*ms) \(").Groups[1].Value;
|
|
|
|
|
Use a Regular Expression, check out <a href="http://www.ultrapico.com/Expresso.htm">Expresso</a>[<a href="http://www.ultrapico.com/Expresso.htm" target="_blank" title="New Window">^</a>] or my own <a href="http://www.codeproject.com/KB/string/RegexTester_.aspx">RegexTester</a>[<a href="http://www.codeproject.com/KB/string/RegexTester_.aspx" target="_blank" title="New Window">^</a>].
|
|
|
|
|
You may want to consider using my StringParser [^] class.
string mSec = string.Empty;
StringParser sp = new StringParser (s);
if (sp.skipToEndOf (") ") && sp.skipToEndOf (") ")) {
sp.extractTo ("(", out mSec);
}
/ravi
|
|
|
|
|
Hi
My application recieves a stream of images from an IP camera. The images are stored as byte arrays. Does anyone know how to get the BITMAPINFOHEADER from the images?
Thanx
|
|
|
|
|
|
Thanx for the reply
Im using MJPG, I dont think that the images are recieved in BMP format. Isnt there some method I can use to extract the BITMAPINFOHEADER?
Im having trouble writing the images to a avi file because of the format the images are in. Im having to change the image format before writing to video file which is to slow.
Thanx
|
|
|
|
|
Dear Sir,
can you tell me when do i use struct and when i use class
|
|
|
|
|
Use a struct if you have no need for methods or to use inheritance and you only need a structure to store data (remember that a struct is passed by value and an object is passed by reference in C#).
|
|
|
|
|
I'm sorry, but that answer is wrong in so many ways: A struct can have methods, (and properties, and events), and can inherit from interfaces. It is true that it is automatically sealed, so you cannot inherit from a struct, but a struct can inherit if it needs to.
A struct is an object, just it derives from System.ValueType which forces it to be stack allocated rather than heap. It is this that means it is passed by value rather than by reference, nothing else.
You should never use standby on an elephant. It always crashes when you lift the ears. - Mark Wallace
C/C++ (I dont see a huge difference between them, and the 'benefits' of C++ are questionable, who needs inheritance when you have copy and paste) - fat_boy
|
|
|
|
|
I'm afraid your answer is also wrong. Structs are not forced to be stack allocated. The runtime simply chooses to use the stack in a limited set of circumstances just because it can. However, your statement about passing by value instead of reference is correct and points to the real distinction between structs and classes.
|
|
|
|
|
You are right, I'm wrong
Structs (and all ValueType derived objects) can be allocated on the heap - for example they are if they are part of a class instance.
If I had been involved, the only difference between a struct and a class would have been:
"structs are imutable, classes are not".
I personally think the "stack / heap" and "value / reference" distinction makes it harder to read code and work out what is happening: all parameters should be pass-by-reference unless otherwise specified - and yes, I do know stack allocation improves performance...
But I wasn't involved, so we have to live with it...
You should never use standby on an elephant. It always crashes when you lift the ears. - Mark Wallace
C/C++ (I dont see a huge difference between them, and the 'benefits' of C++ are questionable, who needs inheritance when you have copy and paste) - fat_boy
|
|
|
|
|
You want to make .NET even slower than it already is?
Or would you make int/float/etc ugly special cases - in which case performance would still be impacted sometimes (but less often)
|
|
|
|
|
OriginalGriff wrote: structs are imutable, classes are not
Structs should be immutable but are not forced to be. System.Drawing.Size IIRC (not at a dev machine at the moment) is an example where MS haven't enforced this - both Width and Height properties are settable
Also many structs used for P/Invoke by necessity are mutated by unmanaged code.
It's a good rule to follow and will avoid major problems if used in a hash set of some description (the hash code will probably be invalid if it's mutated), but it's not set in stone.
[edit] Just realized you were stating what you would have done if you were involved in the C# spec, not how it actually is! Apologies! [/edit]
DaveIf this helped, please vote & accept answer!
Binging is like googling, it just feels dirtier. (Pete O'Hanlon)
BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)
|
|
|
|