|
Monkeyseesaw posted:I haven't worked with XNA much but their use of structs seems like they got a bunch of C++ devs designing it. There's a lot of PODs in XNA that they implemented as structs but as people in this thread are rapidly discovering value-type semantics in .NET are a bit more subtle then just "POD == struct type". I haven't dabbled with XNA much, though I did play with MDX "back in the day" - back when it was a simple wrapper around Direct3D. They used structs because they had the exact same in-memory layout as native Direct3D objects which means that passing them into D3D's functions was cheap as chips. You can't use StructLayout on a class, after all. Had they used reference types then things get complicated quickly, as well as slowed down: D3D's functions expect specific data type layouts which you cannot get with classes, a class-to-struct conversion would be too expensive given you have to pump several million Vector3 instances into the GPU for a single frame now.
|
# ? Jun 25, 2011 01:15 |
|
|
# ? May 15, 2024 01:50 |
|
Monkeyseesaw posted:I haven't worked with XNA much but their use of structs seems like they got a bunch of C++ devs designing it. There's a lot of PODs in XNA that they implemented as structs but as people in this thread are rapidly discovering value-type semantics in .NET are a bit more subtle then just "POD == struct type". I think the C#/VB perspective is that mutable structs are evil. (Do a search for "mutable struct" and "eric lippert" for zillions of pages telling you why...) The framework perspective is that the framework authors invariably want to make mutable structs for performance reasons, e.g. System.Collections.Generic.List(Of T).Enumerator. And for async, we're making "TaskAwaiter" be a structure. The reason is just so that performance of the common case isn't hindered. The XNA perspective is that game developers like to avoid as much heap allocation as possible -- don't want GC to interfere with their frame rate! -- and so they use structs. We haven't yet found a happy compromise. We had discussed changing the VB language so that things like "Foo.p.X = 15" gets rewritten to something like "Foo.p = new Vector2(15, Foo.p.Y)", but that'd probably be a bad idea because there'd be too much going on under the hood and it doesn't work in more complex expressions.
|
# ? Jun 25, 2011 01:32 |
|
No Pants posted:The sleep should be running on a thread in the thread pool in the example. Are you putting your asynchronous activities inside a Parallel or ParallelForEach activity? The workflow thread will execute them one at a time if you don't do that. Thanks, now it makes sense
|
# ? Jun 25, 2011 01:33 |
|
Hoborg posted:Had they used reference types then things get complicated quickly, as well as slowed down: D3D's functions expect specific data type layouts which you cannot get with classes, a class-to-struct conversion would be too expensive given you have to pump several million Vector3 instances into the GPU for a single frame now. Yeah that makes sense, and occurred to me literally as I was writing my last post. ljw1004 posted:I think the C#/VB perspective is that mutable structs are evil. (Do a search for "mutable struct" and "eric lippert" for zillions of pages telling you why...) Yeah believe me I've read quite a bit on implementing value types in .NET because it's a bit of a high-wire act to get the semantics right. Which is why I found it interesting that XNA seemed so struct heavy but given the constraints in pushing data to the directx pipeline it makes some sense. I mostly work in ASP.NET and I can probably count on one hand the number of times I've actually needed to implement a struct of my own. It just doesn't come up very often in most application domains, as opposed to C++ where struct is basically just an annotation meaning "this object is just a data bag, go wild".
|
# ? Jun 25, 2011 03:13 |
|
So then is it bad to make structures that don't follow those rules? I've made a few for games, like one that just wraps a boolean and uses an indexer to treat every bit in it like its own boolean. It's mutable but works nicely to squeeze as much info as possible into the smallest space possible when making files or whatever. The 16 byte limit I understand is because anything over 16 bytes takes significantly longer to copy than a reference, so that's reasonable. And the POD constraint is reasonable with the size limitation. I guess what I'm saying is, is it that important to even really follow these semantics? Is it one of those "as long as you're consistent in your codebase" kind of things? And if not, then what are good rules of thumb to follow? Trying to nip bad coding habits in the bud since I hate refactoring things when I realize I did something stupid.
|
# ? Jun 25, 2011 06:13 |
|
It really depends on what you're using them for. Avoiding mutable structs is usually a good reason if your intent is to have other devs use them, since the value semantics can get confusing if you can both pass something by value AND change the value inline; it's easy to write code that makes you think you're changing one instance when you're actually changing another, or situations where a seemingly innocent operation ends up mutating something unexpectedly. Again Eric Lippert has some good writings in this area. The point of a struct is to provide a type that uses value semantics instead of reference semantics which usually means you have to define your own comparison operators and hash functions which can be non-trivial and if you get them wrong may cause your type to behave in unexpected ways. Again this is really only a major concern if your intent is to provide the strcut for general use; if it's only use in your own projects then knock yourself out. Having said that, value semantics in my experience don't come up very often beyond the built-in types, though obviously this is dependent on the problem domain. Newbies to .NET, especially people from a non-managed code background often want to favor structs over classes to "save memory" since they read somewhere that structs are allocated on the stack while classes are allocated on the heap. Ignoring the fact that in a GC'ed language this is a distinction you rarely have to care about it's also only sort of true. An int may be allocated on the stack but an array of ints still ends up in the managed heap because Array is a reference type. Similarly an int that is a member field of a class. It's so exceedingly rare a value type will be defined whose usage doesn't include appearing in collections or as data fields the memory usage argument is essentially irrelevant.
|
# ? Jun 26, 2011 07:32 |
|
Out of interest I just fetched the 2010 version of Microsoft's official C# newbie book (Visual C# 2010 Step By Step) off the shelf to see what it had to say on the topic. Surprisingly it goes into a fair bit of depth about stack vs. heap allocation in the chapters to do with value vs. reference types and boxing/unboxing, but makes no mention of struct (im)mutability at all. So really this kind of thing goes one step further than Monkeyseesaw's point, in that Microsoft's own training documentation makes quite a big deal of structs performing better due to being on the stack. That's going to push people reading that material towards using them more than they otherwise might, so it does seem strange that there's no discussion of mutability or any of the other struct guidelines for that matter. I definitely see the reason for the "mutable structs are evil" guideline, although maybe "evil" is a bit strong. It's all too easy to treat them as a class and forget that you're working with a local copy when passing them around. rolleyes fucked around with this message at 10:24 on Jun 26, 2011 |
# ? Jun 26, 2011 10:19 |
|
Is there a way to specify direction on a GZipStream like you can on a CryptoStream?
|
# ? Jun 27, 2011 01:04 |
|
rolleyes posted:I definitely see the reason for the "mutable structs are evil" guideline, although maybe "evil" is a bit strong. It's all too easy to treat them as a class and forget that you're working with a local copy when passing them around. Eric Lippert generally frames it as structs don't really own their own memory like classes do and that can lead to weird cases if a struct is mutable.. You can write code that transforms "this" in a mutable struct and literally makes it a new instance, where you can't do that with classes. That said obviously it's a rule of thumb and mutable structs can be found in the .NET framework. They're just not very common. That's interesting that the beginner book emphasizes the memory aspect of it, as the advanced stuff seems to explicitly downplay it in favor of focusing on the semantics of structs vs classes. It's probably the simplest and most obvious differentiating feature if you want to get the point across quickly.
|
# ? Jun 27, 2011 05:58 |
|
Time to give something back. I came to C# after LINQ was already incorporated (so was never around for all the Big New Thing explanations and discussion) and have kind of been blindly using it without ever stopping to understand how it all works underneath. I'm one of those people who sooner or later has to know, so after a lot of Googling and a fair amount of 'bwuh?' moments I came across these two articles: #1. Basics of LINQ and Lambda Expressions #2. Understanding Expression Trees #1 does an excellent job of explaining how LINQ works from the ground up, including the internal structure of the various IEnumerable extension methods (particularly the use of Func) defined in Enumerable which was the part I was scratching my head on for a while. If you want to go a bit deeper #2 covers expression trees, which has to do with translation from, say, LINQ to SQL. Both articles are by the same guy and there are a few others by him linked in the sidebar which seem informative as well. rolleyes fucked around with this message at 22:32 on Jun 28, 2011 |
# ? Jun 28, 2011 22:30 |
|
So I want to make a quick and dirty web service with Visual Studio and .net 3.5. It has to mimic an existing terrible web service so what I need is an entry point of "here is a web request, go wild, put your output here". None of the project templates seem to offer this. Can anyone tell me how I do this? (note, the web service has absolutely nothing to do with SOAP or XML of any kind) EDIT: looks like WCF can be made to do what I need. Zombywuf fucked around with this message at 13:06 on Jun 29, 2011 |
# ? Jun 29, 2011 11:02 |
|
Zombywuf posted:So I want to make a quick and dirty web service with Visual Studio and .net 3.5. It has to mimic an existing terrible web service so what I need is an entry point of "here is a web request, go wild, put your output here". None of the project templates seem to offer this. Can anyone tell me how I do this? WCF is very powerful and very complicated. If you make a web project, you can add good old fashioned web services to it, which might be a little simpler if you don't need WCF's additional features.
|
# ? Jun 29, 2011 13:20 |
|
Zombywuf posted:So I want to make a quick and dirty web service with Visual Studio and .net 3.5 WCF is a beast. You might want to look into Kayak. code:
epswing fucked around with this message at 14:39 on Jun 29, 2011 |
# ? Jun 29, 2011 14:30 |
|
If you just need to send XML in response to GET requests, there are very, very few reasons not to just stand up an MVC website and serve whatever you want from the controllers. There is just too much overhead with WCF for very little payoff that I've seen. PS: if you do need a service stack to feel comfortable, check out open rasta.
|
# ? Jun 29, 2011 16:14 |
|
Zombywuf posted:So I want to make a quick and dirty web service with Visual Studio and .net 3.5. It has to mimic an existing terrible web service so what I need is an entry point of "here is a web request, go wild, put your output here". None of the project templates seem to offer this. Can anyone tell me how I do this? Personally, what I do here is just write the web service as a console application. Then I tell apache which .exe files should be run as cgi-handlers. I've been using mono for this because my server is a linux machine. Also, I naturally use VB for it because of the XML literals... code:
code:
ljw1004 fucked around with this message at 17:30 on Jun 29, 2011 |
# ? Jun 29, 2011 17:13 |
|
^^^ in that spirit, I forgot to mention what might be the cooler, more interesting option out there: https://github.com/jacksonh/manos Personally would love to see someone bake a F#-based node.js - inspired framework but I'm not good enough to write it myself.
|
# ? Jun 29, 2011 19:06 |
|
I'm writing a simple web app in ASP.NET which allows users to search for items in a database, pick a record of interest (which populates a Panel with editable items), then update the items in the Panel which ultimately translates into an update of the underlying field of the database. Suppose the user searches over the Customer table with the string "Joe". Several records are returned which match this. The user clicks one of the results, and the Panel shows the attributes of each record (first name, last name). My question: how do I manage the "key" of the user that has been selected? It's a Guid string - I need to store this somewhere that's not user-visible so that I can find the relevant record and perform the updates when the user clicks 'Save'. Is this something I should be using the Session construct for?
|
# ? Jun 30, 2011 06:41 |
|
Lexicon posted:I'm writing a simple web app in ASP.NET which allows users to search for items in a database, pick a record of interest (which populates a Panel with editable items), then update the items in the Panel which ultimately translates into an update of the underlying field of the database. I would use a hidden field in the table.
|
# ? Jun 30, 2011 06:49 |
|
Sprawl posted:I would use a hidden field in the table. Ok, thanks. This is a fairly standard practice I guess?
|
# ? Jun 30, 2011 06:52 |
|
I've gotten on a BDD kick using SpecFlow to write easy-to-understand specification tests and develop against them. It's working out great for a lot of my automated processes, where I reference a service class and use dependency injection/mocking to replace the standard data access layer with data specifically designed for the test. But now I have to write some specifications against the website UI. This guy shows off on how he does this with his web UI, and I really like his approach. EXCEPT he's not doing anything about mocking up the data contexts... it looks like it hits the real development database. This seems like it would make my tests brittle and only work if they run in a specific order (TestAddUser has to run before TestDeleteUser, and they must BOTH run every time or next time one will fail). My web application is using an IOC container as a property on the global application. So I'm left wondering if there's some way my nunit tests can access the IOC container on a running instance of IIS express and replace the DAL components for specific tests. That way I can ensure that wen TestAddUser() runs there are no users in the mocked DAL, and when TestDeleteUser() runs the expected user always exists. Does anyone have any experience with this? Any ideas on how I might have a test project access the global application of a referenced web application running in IIS Express? Or am I completely out of luck?
|
# ? Jun 30, 2011 14:00 |
|
FYI: Official Release of Rx
|
# ? Jun 30, 2011 14:56 |
|
epswing posted:FYI: Official Release of Rx FINALLY. Been waiting for that for ever.
|
# ? Jun 30, 2011 16:28 |
|
What ever happened to System.Interactive? It's been removed from the latest versions of Rx.
|
# ? Jun 30, 2011 16:46 |
|
We have a lot of classes that raise events, and typically those events only contain a single piece of data. For example, a configuration value changed, and the event args will contain the new configuration value. To prevent having to create (and test) a ton of one-off EventArgs classes in our solution, we've created a generic EventArgs<T> that can be used in most circumstances. (Obviously, if complex data needs to be passed in the EventArgs, we write a custom EventArgs class for that.) So, we've got events in classes that look like this: public event EventHandler<EventArgs<int>> SomeIntEvent; Raising these events always takes the same form: code:
code:
EventRaiser.RaiseGenericEvent(SomeIntEvent, someIntValue, this); Is this a horrible idea? Really hasty testing suggests that it works as expected. But I've also read that you can't raise events outside the class that owns them. Thoughts?
|
# ? Jun 30, 2011 17:32 |
|
You know about extension methods, right? code:
code:
code:
|
# ? Jun 30, 2011 17:41 |
|
My app requires network discovery. I have a list of IP addresses and quickly want to suss out which ones are 'good' - basically which ones the app can connect to. At first I was using System.Net.NetworkInformation.Ping but that has 2 drawbacks. The async versions don't work with multiple outstanding pings and a lot of IT departments block ping from being routed. I switched to using WebRequest but saw issues with attempting to make a bunch on connections in a short amount of time. I would get timeouts with IP addresses that were addressable and a wireshark capture showed that the pc wasn't sending anything out in these cases. I figured I was running into ServicePointManager limitations and playing with MaxServicePoints, DefaultConnectionLimits and MaxServicePointIdleTime didn't fix the problem. MaxServicePointIdleTime appeared to help somewhat but not completely. I then decided to switch to just using a TcpClient and making a connection to port 80 - if the connection succeeds the machine is out there. While it works better than WebRequest I still see cases where I get timeouts on machines that are definitely reachable. It shouldn't be actually timing out since I've set the timeout on the TcpClient to 1000ms and increasing that value doesn't change the behavior. What does change it is putting a small delay ( 10ms ) between each TcpClient.BeginConnect call. This makes me think that there is some limitation to the number of Tcp connections I can make. I'm not trying to make a huge number of connections - right now I'm testing with 18 IPs, 12 of which should be reachable. Are there basic limitations with TCP connections either in .NET or Windows itself? I'm currently testing on Win7 x64 if that matters.
|
# ? Jun 30, 2011 17:46 |
|
_aaron posted:Is this a horrible idea? Really hasty testing suggests that it works as expected. But I've also read that you can't raise events outside the class that owns them. Thoughts?
|
# ? Jun 30, 2011 18:11 |
|
fankey posted:Are there basic limitations with TCP connections either in .NET or Windows itself? I'm currently testing on Win7 x64 if that matters. I've not heard actual confirmation of this, but I believe it's a .NET limitation. When we wanted to load-test a web-server we switched to native. Another issue is that even async HttpWebRequest still does DNS lookup synchronously.
|
# ? Jun 30, 2011 19:16 |
|
I've got a quick question about using database Views in Entity Framework. Other than the annoying warning I get about not having primary keys defined, this has been working ok in the few cases where we used db views with EF. Now, I have a view I want to pull in that's all aggregate data (it's a summary of calls by month), so there are no non-nullable columns found when the view is imported to the designer. This results in the entity information commented out in the edmx file and unusable in the project. What I've been able to do is, using this msdn reference, edit the edmx file so I can use the view as an entity. This works great, until I update the model from the database again, which overrides my changes. I guess I'm interested in knowing if anyone else makes much use of views in EF 4, and if I'm missing something obvious in making this easier.
|
# ? Jun 30, 2011 19:52 |
|
epswing posted:FYI: Official Release of Rx Oh finally, this means we'll get up to date documentation. Or at least a homepage which doesn't link to a hands on lab PDF that tells you to reference assemblies which no longer ship or extension methods which no longer exist. Neither of which helps when it comes to trying to grok Rx. Half the time it's just easier to write drat multi-threaded code manually. Possibly because whilst you're writing boilerplate code, you're actually thinking about the important part.
|
# ? Jun 30, 2011 23:12 |
|
Frequently I have some data that I want to view in different ways. I want to use the UI to switch between the different views. I might do something like this:pre:<StackPanel> <ContentControl Content="{Binding MyContent}"> <ContentControl.Style> <Style TargetType="{x:Type ContentControl}"> <Setter Property="ContentTemplate"> <Setter.Value> <DataTemplate> <GroupBox Header="First view of my content"> <TextBlock Foreground="Blue" Text="{Binding Mode=OneTime}"/> </GroupBox> </DataTemplate> </Setter.Value> </Setter> <Style.Triggers> <DataTrigger Binding="{Binding SelectedViewMode, Mode=OneWay}" Value="Second"> <DataTrigger.Setters> <Setter Property="ContentTemplate"> <Setter.Value> <DataTemplate> <GroupBox Header="Second view of my content"> <TextBlock Foreground="Green" Text="{Binding Mode=OneTime}"/> </GroupBox> </DataTemplate> </Setter.Value> </Setter> </DataTrigger.Setters> </DataTrigger> <DataTrigger Binding="{Binding SelectedViewMode, Mode=OneWay}" Value="Third"> <DataTrigger.Setters> <Setter Property="ContentTemplate"> <Setter.Value> <DataTemplate> <GroupBox Header="Third view of my content"> <TextBlock Foreground="Red" Text="{Binding Mode=OneTime}"/> </GroupBox> </DataTemplate> </Setter.Value> </Setter> </DataTrigger.Setters> </DataTrigger> </Style.Triggers> </Style> </ContentControl.Style> </ContentControl> <ComboBox ItemsSource="{Binding ViewModes, Mode=OneTime}" SelectedItem="{Binding SelectedViewMode, Mode=TwoWay}" /> </StackPanel> // ViewModel/DataContext: public object MyContent { get { return "Content!"; } } public enum ViewMode { First, Second, Third, } [INPC] public ViewMode SelectedViewMode { get; set; } // Fires INPC public IEnumerable<ViewMode> ViewModes { get { return (IEnumerable<ViewMode>)Enum.GetValues(typeof(ViewMode)); } } pre:<ViewSwitcher CurrentView="{Binding SelectedViewMode, Mode=OneWay}"> <GroupBox ViewSwitcher.View="First" Header="First view of my content"> <TextBlock Foreground="Blue" Text="{Binding Mode=OneTime}"/> </GroupBox> <GroupBox ViewSwitcher.View="Second" Header="Second view of my content"> <TextBlock Foreground="Green" Text="{Binding Mode=OneTime}"/> </GroupBox> <GroupBox ViewSwitcher.View="Third" Header="Third view of my content"> <TextBlock Foreground="Red" Text="{Binding Mode=OneTime}"/> </GroupBox> </ViewSwitcher>
|
# ? Jun 30, 2011 23:42 |
|
Milotic posted:Oh finally, this means we'll get up to date documentation. Or at least a homepage which doesn't link to a hands on lab PDF that tells you to reference assemblies which no longer ship or extension methods which no longer exist. Neither of which helps when it comes to trying to grok Rx. Half the time it's just easier to write drat multi-threaded code manually. Possibly because whilst you're writing boilerplate code, you're actually thinking about the important part. I must apologise for refusing to stop living in 2005 (.NET 2.0 forever!) but can someone explain, very quickly, what Rx is and what it enables/allows developers to do that they couldn't do before? I'm perfectly happy with using Threads and pools, Mutexes, Wait Handles, and Semaphores directly. In GUI work I'm fine with Invoke/BeginInvoke and that works perfectly fine for me. About 18 months ago, a friend spoke of how some concurrency platform Microsoft built (the same thing?) provided stuff that automagically broke down massively-parallel tasks down for multicore systems (like a single-system map-reduce). Is that what this is for? Today I'm finding myself doing LoB applications and stateless web-services. How will Rx help me? Am I in the target audience?
|
# ? Jul 1, 2011 17:17 |
|
Hoborg posted:I must apologise for refusing to stop living in 2005 (.NET 2.0 forever!) but can someone explain, very quickly, what Rx is and what it enables/allows developers to do that they couldn't do before? What your friend is probably talking about is the Parallel task library, which is new in .NET 4 and is awesome. I mean, what's going to be easier to maintain and debug? Writing a shitload of concurrency code, or doing Parallel.ForEach()? Rx is for doing work asynchronously without starting up a new thread. Also, I hope you're kidding. .NET 3.5 and 4.0 have some awesome, awesome features and if you're not familiar with them, you should be. New Yorp New Yorp fucked around with this message at 22:51 on Jul 1, 2011 |
# ? Jul 1, 2011 22:48 |
|
Ithaqua posted:Rx is for doing work asynchronously without starting up a new thread. Surely Rx is still creating and managing threads in the background? Ithaqua posted:Also, I hope you're kidding. .NET 3.5 and 4.0 have some awesome, awesome features and if you're not familiar with them, you should be. With the exception of C#'s new language features (auto-implemented properties, Lambda expressions, extension methods, and Linq) and LINQ itself (mostly Linq-to-SQL and Linq-to-Entities). So I should rephrase and put .NET 3.5 with C# 3.0. But that said, 90% of my work can be done just as well with .NET 2.0, other things I could swap-out, like Linq for data replaced with NHibernate, or WCF with the older ASMX (or even pure ASP.NET for RESTful services).
|
# ? Jul 1, 2011 23:43 |
|
Hoborg posted:Surely Rx is still creating and managing threads in the background? No... For instance: Imagine I set up an IObservable (i.e. an RX event stream) such that every time the user clicks a button, then it generates another event. Then I subscribe to that IObservable (i.e. provide a lambda which is executed each time an event comes along). When Winforms/WPF/whatever gets a button-click, it generates the Rx event. This then invokes the lambda. No threads were created or managed in this process.
|
# ? Jul 2, 2011 00:12 |
|
ljw1004 posted:No... But that sounds like normal synchronous programming to me. Where's the async?
|
# ? Jul 2, 2011 01:13 |
|
ljw1004 posted:No... You sure there is no multi-threading going on? There is some example code out there that very clearly shows code running on several threads by outputting the Managed Thread ID.
|
# ? Jul 2, 2011 02:01 |
|
Rx is no more "async" than regular .NET events. It's really just LINQ for push-based collections. It does have facilities for multithreading similar to LINQ+TPL, but that's not its primary purpose. I wouldn't recommend Rx unless you're comfortable with LINQ. It's definitely more complex and I'd say it has fewer use cases. You can get by "perfectly fine" without LINQ, Rx, TPL, closures and other new features but you'll be writing much more boilerplate.
|
# ? Jul 2, 2011 02:08 |
|
The part of Rx I'm excited about is the grouping capabilities. You can say "take all the objects that come out of this ienumerable for 1 second, and then group them together, and call an event with that collection" with one argument, for example.
|
# ? Jul 2, 2011 15:01 |
|
|
# ? May 15, 2024 01:50 |
|
fankey posted:At first I was using System.Net.NetworkInformation.Ping but that has 2 drawbacks. The async versions don't work with multiple outstanding pings It's a general rule that any class in the framework with methods that support the async pattern can only be used to have one async operation in progress at a time. If you want to do multiple asynchronous pings, you should create multiple instances of the Ping class and start one async ping on each instance, which will work as expected; rather than trying to start multiple async pings from one instance of the class, which will fail. fankey posted:I switched to using WebRequest but saw issues with attempting to make a bunch on connections in a short amount of time. There may be one of three things at play here: Some editions of Windows (Windows XP SP2 and later; and Windows Vista prior to SP2) cap the number of half-open connections allowed (sockets where a connection request has gone out, but the remote server hasn't responded yet), as a way of trying the limit the impact of certain types of malware that used to be common. This very much affects trying to scan a network. There's no way around this short of using a server edition of Windows; because last I remember the limit wasn't configurable, you'd have to hex edit tcpip.sys to change it. This would cause the timeouts you were seeing too, because the timeout timer starts as soon as the connection request is handed off to the networking stack; not when the request is actually cleared to go out. This wouldn't affect pings, though; since pings are ICMP, which isn't a connection-oriented protocol. Nor would it affect UDP, for the same reason. It only affects TCP. The second thing that could be getting in the way of what you're trying to do is that WebRequest imposes a connections-per-host limit in a way similar to how web browsers limit connections-per-host; meaning that by default WebRequest won't open more than two simultaneous connections to the same host. This can be overridden by tweaking your application's configuration file. This limit has no effect on simultaneous requests to multiple hosts. And finally, it's possible that you're starving the managed ThreadPool. Async network operations usually deliver their completion event on a ThreadPool thread. As ThreadPool threads are intended for small, fast operations and to avoid the overhead of excessive context switching, the ThreadPool tries to keep the number of threads running as low as possible, down to the number of physical cores you have. However, if stuff is queued up, it will reluctantly (after a 500ms delay) start spinning up new threads, up to a hard limit. These numbers are all configurable (both the lower and upper bound on threads). If you're doing an expensive blocking operation in direct response to an AsyncResult callback handler, this might be the reason why performance suddenly tanks without an apparent reason after a certain number of simultaneous operations. fankey posted:Are there basic limitations with TCP connections either in .NET or Windows itself? I'm currently testing on Win7 x64 if that matters. .NET itself imposes no limits at all on network usage. I personally have written servers in .NET that handle and make literally thousands of simultaneous connections without any sort of issue. biznatchio fucked around with this message at 15:57 on Jul 2, 2011 |
# ? Jul 2, 2011 15:49 |