|
Luc Pattyn wrote: All is fine if the outside world cannot touch the lock object, so if you have say a return _collection; somewhere, then the first is no good.
If you have a return _collection, you must expose whatever lock object you're using. You may as well use _collection itself as the lock object (and mandate that anyone who does anything with that collection do likewise). Returning _collection without exposing its lock object a guaranteed disaster. The idea that one should avoid exposing the lock for an exposed non-threadsafe object is absurd.
If a non-threadsafe object is accessed by two routines in different threads, the two routines must use the same lock object to arbitrate access. If the routines use different lock objects, nothing will prevent illegitimate concurrent access. I have no idea why this issue doesn't seem to be amplified more.
BTW, I also have no idea why Microsoft didn't come up with a more useful contract for iEnumerable--one that would allow for a collection to accept modifications during enumeration without throwing an exception, provided certain constraints were met.
|
|
|
|
|
you're right all the way.
Exporting a collection that uses a lock but does not make it available is absurd, and making it available is dangerous. Probably best is to provide the required functionality without exporting either the collection nor the lock. I'll have to remember not to start a sentence with "All is fine if".
For collections there should at least be an enumerator that allows modifications to the elements that have already been visited including removal from the collection, so one could e.g. easily remove elements that satisfy some conditions while enumerating them all. I understand it may be hard to come up with an implementation that is safe and inexpensive at the same time.
|
|
|
|
|
Luc Pattyn wrote: For collections there should at least be an enumerator that allows modifications to the elements that have already been visited including removal from the collection, so one could e.g. easily remove elements that satisfy some conditions while enumerating them all.
I would think there should be. Unfortunately, Microsoft's contract for iEnumerable/iEnumerator explicitly forbids them from even allowing such a thing; it requires that an attempt to fetch the next item from an iEnumerator throw an exception if any change has been made to the underlying iEnumerable even if the iEnumerator would otherwise be able to return something useful. Note that the vb6-style "Collection" object does not conform to this but instead returns useful data (hooray!) Too bad no other collections behave similarly.
If I had my druthers, an iEnumerator would be only be required to throw an exception if it couldn't otherwise meet the following contract:
- Any item that exists throughout the enumeration will be returned exactly once in each pass through the enumeration.
- Any item that is added and/or removed during the enumeration will be returned zero or one times (a removal and re-add may create a "new" item) in any pass.
- For collections with keys, changing a key may be regarded as a remove and add, which may be performed in either order.
- Items will be returned in a sequence consistent with the contract (e.g. if a particular collection is supposed to return items in sorted order, adding and deleting items should not cause items to be returned out of sequence).
- If the effect of an addition or removal is observed in one pass through the enumeration, it will be observed in subsequent passes.
For some types of collection, it would be difficult to meet this contract. Such collections should throw exceptions if they're modified during enumeration. On the other hand, if a collection can meet the above conditions even if it's changed during enumeration, why shouldn't it be allowed to?
|
|
|
|
|
I agree, that would be nice to have. I expect MS considers it too complex to sell; the existing stuff is very easy to explain, and they most often seem in favor of dumbing things down... ("You can always clone the collection!")
|
|
|
|
|
To whom would such a contract be 'too hard to sell'? If it would be too difficult to make a collection work nicely, it would be free to throw an exception. Provided that there's a means of determining whether a collection has been changed, I really don't see any advantages to requiring the exception. Further, if Microsoft was willing to disobey the contract on the vb6-style "Collection", why not offer any more useful form of collection that does likewise?
BTW, what would be the proper behavior for a collection which will require a .Dispose call to avoid a memory leak? To implement iEnumerable(of T) as well as iEnumerable, but throw NotImplementedException when a call is made to the non-generic GetEnumerator?
|
|
|
|
|
The way I see it, the programmer needs to be able to predict the behavior, so he can code accordingly. With a more complex behavior a class would risk to be less popular and/or lead to accidents, such as unexpected exceptions (because the user did not understand the contract well).
the vb6-style "Collection" looks like a compromise: what to do to ease VB->VB.NET upgrades while adhering to the .NET conventions? IMO they try to tell us a VB Collection is and is not a collection at the same time.
|
|
|
|
|
The way I see it, the programmer needs to be able to predict the behavior, so he can code accordingly. With a more complex behavior a class would risk to be less popular and/or lead to accidents, such as unexpected exceptions (because the user did not understand the contract well).
I guess I don't really see a whole lot of situations where the exception behavior is more useful than the behavior I described, especially since--if iEnumerator provided a collectionChanged property--one could code a generic class that, given an iEnumerator(of T), would implement iEnumerator(of T) but throw an exception if an effort was made to fetch an item after the underlying class had changed. Thus, if one wanted to have a "For Each" loop that would throw an exception if the collection changed, one could write:
For Each myThing as myClass in New ProtectedEnumerable(myCollection)
...
EndIf
Since one new generic ProtectedEnumerable() class could make any iEnumerable implement the present more-strict contract, I would think the less strict contract would be more useful.
If it were possible to simply implement and use an iNiceEnumerable which followed a different contract, I wouldn't mind the behavior of iEnumerable. As it is, however, iEnumerable and iDisposable are both hard-coded into the compilers for C# and VB.net; if a collection doesn't implement an interface which is called iEnumerable, it can't be used with for-each loop. Even if it would be useful to have an interface defined that implements Microsoft's strict contract, I don't think it's very nice to declare that only interfaces that adhere to that strict contract should be used in for-each loops.
Also, with regard to programmer confusion, it seems far less confusing to say that one must use certain collection types if one is going to modify a collection during enumeration, than to say that one must write enumeration code as:
Using MyNiceEnum as iNiceEnum(of MyThing) = myNiceCollection.GetNiceEnum
Dim MyItem as MyThing
While MyNiceEnum.GetNext
MyItem = MyNiceEnum.TheItem
.. Do something with MyItem
End While
End Using
as opposed to:
For Each MyItem in myNiceCollection
.. Do something with MyItem
Next
|
|
|
|
|
Now think about the implementation details of a protected collection. Most if not all collections are built on top of an array, which gets reallocated and copied every time the capacity becomes insufficient, and which gets insert/remove-shifted on each insertion or removal.
Such collection can have any number of users (methods, possibly active on different threads), each possibly holding one or more enumerators; each enumerator has its own state. Now insert or remove a collection item; how could the collection tell which protected enumerators get affected by the modification, and which don't (because they are already past the insertion/removal point). The natural way would be one of these:
1.
inside the collection, keep a collection of current enumerators and check each of them on every modification, not a pretty situation. (Note: there are life issues, probably needs WeakReferences)
2.
for each enumerator, create a copy of the array, basically cloning the collection. An expensive operation.
The current .NET behavior can easily be accomplished by having a "generation number" which is stored in the collection, incremented on every insert/remove, and gets copied into the enumerator when it gets created, then compared on every Next(). None of these are expensive, memory wise of cycle wise.
|
|
|
|
|
My contract could be just as easily honored. All any of the existing collection classes would have to do honor my 'improved' contract would be to behave exactly as they already do.
My complaint with the Microsoft's iEnumerable contract is that rather than merely requiring an enumerator to throw an exception if the collection has been modified in a way the enumerator can't sensibly handle, it requires that the enumerator throw an exception if the collection is modified, period. That seems unduly harsh.
If someone codes a collection using e.g. a linked list, such that insertions and deletions can be handled without disturbing enumeration (subject to the constraints I listed), is there any reason to forbid its enumerator from operating through insertions and deletions? I know that, from a practical standpoint, Microsoft isn't going to break the kneecaps of any programmer who has the audacity to do such a thing, but it still seems irksome that the best approach would be something Microsoft has declared to be wrong.
|
|
|
|
|
|
I don't think this is new or strange. You obviously can't use upper versions of framework components from lower versions.
I know the language. I've read a book. - _Madmatt
|
|
|
|
|
Actually I just had a similar experience:
a solution with one 3.5 EXE project referencing two 2.0 DLL projects; it was created long ago with 2008 without any problem (initially it was all 2.0, but then the EXE needed some LINQ and I never got around to modify the DLL targets). When ported to VS2010 I had to modify the DLL projects so they now all target the same framework.
|
|
|
|
|
Yes, but why VS2008 did not make this a problem on compiling?
I agree with you when you say you can't use upper framework form a 2.0 assembly, 'cause, for example it can be deployed on a win2000 or on a machine without .NET 3.0.
But as I say in my previous post, I'll deploy this solution on .NET 3.5 ready machines; only a bug/limit of Cobol<->.NET bridge force me to compile only this Cobol-.NET-interface-assembly in 2.0.
However, I found the trick: reference System.Core.dll (or other dll needed by your referenced assemblies) by hand.
Thanks!
Nando
Jesus
|
|
|
|
|
Hi,
Currently i am using VS 2008 in my PC, now i am planning to install VS 2010 Ultimate in my PC. is its going to effect to my existing applications,if i install this . i want to use my VS 2008 Applications as it is(Don't want to upgrade existing Applications). please suggest me. if it's effects i will roll off from the idea of installing VS2010.
Thanks in advance..
fttyhtrhyfytrytrysetyetytesystryrty
|
|
|
|
|
No problems here so far. It insists on capturing the .sln extensions and wanting to convert them, but that's minor annoyance. Just tell it to eff off.
|
|
|
|
|
You can use both side-by-side.
I know the language. I've read a book. - _Madmatt
|
|
|
|
|
Public Sub s_zoekEntiteit(ByVal i_entiteit As String)
Dim sqlStr As String = "zoekEntiteit '" & i_entiteit & "'"
Dim dataAdapter = New SqlDataAdapter(sqlStr, m_constring)
Dim commandBuilder As New SqlCommandBuilder(dataAdapter)
Dim DataGridTable As New DataTable()
dataAdapter.Fill(DataGridTable)
Form5.ListBox1.DataSource = DataGridTable
Form5.ListBox1.DisplayMember = i_entiteit
Form5.ListBox1.ValueMember = i_entiteit
End Sub
The Stored Procedure:
CREATE PROCEDURE zoekEntiteit (@tmpEntiteit nvarchar(40))AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
SELECT @tmpEntiteit FROM tblProduct;
--'ByVal i_prodid As String, ByVal i_prodnaam As String, ByVal i_prodomschrijving As String,
--'ByVal i_prodprijs As Int16, ByVal i_prodinstock As String)
END
The RESULT if @tmpEntiteit would be ProdID :
Image to Result
What is wrong here I keep getting an error on ' Form5.ListBox1.ValueMember = i_entiteit' the following error : Can't bind to the new DisplayMember. Paramater newDisplayMember
|
|
|
|
|
I expect its because you don't have a column called i_entiteit in your datatable - your stored procedure returns a column name of (no column name), but as it simply returns the value you pass to it anyway its pointless.
Bob
Ashfield Consultants Ltd
|
|
|
|
|
i am using 3tier design in .net framework,i got two tables called category and menus so i want when i click the button to display in listbox only those who belong in that category..
|
|
|
|
|
And the question is .....?
You haven't provided a question, nor your code, nor any error messages you've gotten, ..., nothing we can use to diagnose your problem.
|
|
|
|
|
Write a query to fetch the appropriate data (those who belong to that category) and then pass it onto the listbox.
|
|
|
|
|
You have not make it clear what how your 3-tier design is related, but concerning your two tables "category" and "menus" you can try INNER JOIN with ON condition which relates the key values in both table.
----------------------------------
Hope it will help you.
|
|
|
|
|
Please provide some detail on your question
so that it is more clearer to answer it.
Jinal Desai
|
|
|
|
|
Hi
can any one help me out in finiding
how to get the mac number of the client system when my application is running in a common server in asp.net
Thanks in advance
Regards,
Gayathri Devi S
|
|
|
|
|
You'll have to seacrh the arp cache. You can find the arp cache in the System.Management; do a query for WIN32_NetworkAdapterConfiguration, and then filter by IP address.
You'll require a full trust environment for this. Note that is NOT the client mac address, but the MAC address of the next hop, if you're connected to a router, or of the bridge if you're connected to a bridge. This will only work in lan environments where clients are connected to switches or hubs.
example here[^]
|
|
|
|