Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
Hoborg
Oct 19, 2006

by T. Mascis

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 can't think of a good reason why the Vector types would need to be structs unless there's some weird under-the-hood optimization they gain when it's all sent to the GPU or something. For whatever reason XNA is a lot more struct heavy than the .NET framework at large, where they typically do stick to the guidelines fairly well.

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.

Adbot
ADBOT LOVES YOU

ljw1004
Jan 18, 2005

rum

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.

Nurbs
Aug 31, 2001

Three fries short of a happy meal...Whacko!

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

Dr Monkeysee
Oct 11, 2002

just a fox like a hundred thousand others
Nap Ghost

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".

Mr.Hotkeys
Dec 27, 2008

you're just thinking too much
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.

Dr Monkeysee
Oct 11, 2002

just a fox like a hundred thousand others
Nap Ghost
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.

rolleyes
Nov 16, 2006

Sometimes you have to roll the hard... two?
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

Casimirus
Mar 28, 2005
Yes.
Is there a way to specify direction on a GZipStream like you can on a CryptoStream?

Dr Monkeysee
Oct 11, 2002

just a fox like a hundred thousand others
Nap Ghost

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.

rolleyes
Nov 16, 2006

Sometimes you have to roll the hard... two?
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

Zombywuf
Mar 29, 2008

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

Dietrich
Sep 11, 2001

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?

(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.

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.

epswing
Nov 4, 2003

Soiled Meat

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:
class Program
{
    static void Main(string[] args)
    {
        // instantiate a server
        var server = new KayakServer();
        
        // tell it we're going to use the Kayak Framework.
        server.UseFramework();
        
        // start listening for connections!
        server.Start();
        
        Console.WriteLine(string.Format("Started server on {0}, " +
            "press enter to exit.", server.EndPoint));
        
        // wait for pending connections to complete before exiting.
        Console.ReadLine();
        
        server.Stop();
    }
}

class ButtService : KayakService
{
    [Verb("GET")]
    [Path("/getbutt/{id}")]
    public void GetButt(String id)
    {
        Response.Write("Hello!  You are looking for butt #" + id);
    }
}
Edit: Hm, Kayak seems to have been overhauled and I can't find the new documentation...

epswing fucked around with this message at 14:39 on Jun 29, 2011

wwb
Aug 17, 2004

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.

ljw1004
Jan 18, 2005

rum

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:
Imports System.Net
Imports System.IO
Imports <xmlns="http://www.w3.org/1999/xhtml">

Module Module1
    Sub Main()
        Console.WriteLine("Content-type: text/xml" & vbCrLf)
        Dim xml = <xhtml>
                      <head>
                          <title>Hello world</title>
                      </head>
                      <body>
                          <p>Hello world</p>
                      </body>
                  </xhtml>
        Console.WriteLine(xml)
    End Sub
End Module
Or for something fancier (using the new Async CTP), to embed code and markup together like you would with PHP but in a typesafe manner:

code:
Dim xml =
  <xhtml>
    <body>
      <ul>
        <%= Iterator Function()
              For i = 1 To 10
                Yield <li>Robot number <%= i %> reporting for duty</li>
              Next
            End Function() %>
      </ul>
    </body>
  </xhtml>

ljw1004 fucked around with this message at 17:30 on Jun 29, 2011

wwb
Aug 17, 2004

^^^ 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.

Lexicon
Jul 29, 2003

I had a beer with Stephen Harper once and now I like him.
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?

Sprawl
Nov 21, 2005


I'm a huge retarded sperglord who can't spell, but Starfleet Dental would still take me and I love them for it!

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.

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?

I would use a hidden field in the table.

Lexicon
Jul 29, 2003

I had a beer with Stephen Harper once and now I like him.

Sprawl posted:

I would use a hidden field in the table.

Ok, thanks. This is a fairly standard practice I guess?

Dromio
Oct 16, 2002
Sleeper
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?

epswing
Nov 4, 2003

Soiled Meat
FYI: Official Release of Rx

Dietrich
Sep 11, 2001

epswing posted:

FYI: Official Release of Rx

FINALLY. Been waiting for that for ever.

Sedro
Dec 31, 2008
What ever happened to System.Interactive? It's been removed from the latest versions of Rx.

_aaron
Jul 24, 2007
The underscore is silent.
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:
var handler = this.SomeIntEvent;
if (handler != null)
{
    handler(this, new EventArgs<int>(someIntValue));
}
I wrote up a static method in a static class to reduce code duplication:

code:
public static class EventRaiser
{
     /// <summary>
     /// Raises an event with generic event args
     /// </summary>
     /// <typeparam name="T">the type of the event args</typeparam>
     /// <param name="eventToRaise">the event to be raised</param>
     /// <param name="argValue">the value of the event arguments</param>
     /// <param name="sender">the event's sender</param>
     public static void RaiseGenericEvent<T>(EventHandler<EventArgs<T>> eventToRaise, T argValue, object sender)
     {
         if (eventToRaise != null)
         {
             eventToRaise(sender, new EventArgs<T>(argValue));
         }
     }
}
So now instead of the "create reference copy of event, check for null, and raise event" flow above, we can just call that static method:

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?

Dietrich
Sep 11, 2001

You know about extension methods, right?

code:
public static void Raise(this EventHandler eventHandler, object sender, EventArgs e)
		{
			if (eventHandler != null)
				eventHandler(sender, e);
		}

public static void Raise<T>(this EventHandler<T> eventHandler, object sender, T e) where T : EventArgs
		{
			if (eventHandler != null)
				eventHandler(sender, e);
		}
code:
public virtual event EventHandler<TestStatusUpdatedEventArgs> TestStatusUpdated;
code:
TestStatusUpdated.Raise(this, new TestStatusUpdatedEventArgs(Status));

fankey
Aug 31, 2001

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.

No Pants
Dec 10, 2000

_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?
You're passing a delegate of type EventHandler<EventArgs<T>> to the static method, which works fine. The restriction on raising events just means that you can't treat the event like a delegate field outside its class.

ljw1004
Jan 18, 2005

rum

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.

MrBishop
Sep 30, 2006

I see what you did there...

Soiled Meat
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.

Milotic
Mar 4, 2009

9CL apologist
Slippery Tilde

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.

Sedro
Dec 31, 2008
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)); }
}
I'm hoping someone has made a control that simplifies all this. For example:
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>

Hoborg
Oct 19, 2006

by T. Mascis

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?

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

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?

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?

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

Hoborg
Oct 19, 2006

by T. Mascis

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).

ljw1004
Jan 18, 2005

rum

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.

Hoborg
Oct 19, 2006

by T. Mascis

ljw1004 posted:

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.

But that sounds like normal synchronous programming to me. Where's the async?

consensual poster
Sep 1, 2009

ljw1004 posted:

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.

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.

Sedro
Dec 31, 2008
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.

Dietrich
Sep 11, 2001

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.

Adbot
ADBOT LOVES YOU

biznatchio
Mar 31, 2001


Buglord

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

  • Locked thread