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.
 
  • Post
  • Reply
BirdOfPlay
Feb 19, 2012

THUNDERDOME LOSER

raminasi posted:

Does MonoDevelop let you set conditional breakpoints? If so, you can drop a breakpoint in the Battle constructor that only breaks when either of the unit references is null. I'm assuming that that shouldn't happen ever, so you'll only break when the bad Battle is being constructed. Then you can examine the call stack to see where you're going wrong.

(This is under the assumption that Battle participants aren't mutable, which is the impression your description gives, and a good idea, precisely because it makes this type of problem easier to fix. If they aren't mutable, then those fields should be declared readonly so that you don't accidentally mutate them at some point.)

In general, unsubscribing from events you no longer need is a good idea, unless there's a performance reason not to. The main reason to do it is that event subscription creates a reference from the event to the subscriber, which can cause you to keep references around longer than you need. I can't tell from your description whether this is causing your problem, though.

They were meant to be non-mutatable, but I had only set up them up as simple properties with a private setter. I did rewrite it with a readonly field behind.

Unfortunately, that didn't change anything nor did my conditional breakpoint ever fire. I even popped in a general one after it to make sure that I had set it up correctly. Granted, I had to comment out the unsubscribe to catch the error. Funny thing is, I don't even get a single MissingReferenceException from Unity (the exception that constantly fires when the game gets stuck in the loop) with the unsubscribe line, which I would expect to get one from the first pass of the bad Battle, even though I unsubscribe to it later. But, given your final point, I guess it makes sense, the MissingReferenceException means that I'm trying to use a reference to a Behaviour that was attached to an object that no longer exists.

Now, I should add something I just discovered from coming back to the code: I'm getting InvalidOperationExceptions from the following. Minor note: this is the CombatManager's Update method, which is called during every draw cycle for the Unity engine.
code:
// Note: curFights is a my List of Battles
// Only do stuff if will have active battles
if (curFights.Count == 0)
{
	return;
}

// Add the time to each battle
foreach (Battle temp in curFights)
{
	temp.AddTime (Time.deltaTime); // Time.deltaTime is how long it's been since the last Update call
}
Now, AddTime adds time to the timers for the two participants and tells them to attack, if enough time has passed. Now, if this attack leads to them being defeated they fire their DeathEvent, etc. I think this might be a cause of some problems, if not most of them. Just so that I'm understanding how events are handled, would this be a correct call stack if AddTime cause the death of a unit?

BattleCompleted - Listens for BattleEvent's from a Battle, does a curFights.remove(this Battle)
OnBattleCompleted - Fires a BattleEvent when a Battle completes, listens for DeathEvents
OnDeath - Fires a DeathEvent
TakeDamage - Called when a unit is attacked, fires OnDeath if health == 0
AddTime - Adds time to the battle timer, calls TakeDamage if enough time has passed
Update

I ask, because I assumed when designing this that events would be handled at the end of the current method call rather than what appears above. I now can see why this was a foolish assumption. I assume that I need to cull the list outside of BattleCompleted to stop this, which seems like a fun, little problem.

Adbot
ADBOT LOVES YOU

raminasi
Jan 25, 2005

a last drink with no ice

BirdOfPlay posted:

They were meant to be non-mutatable, but I had only set up them up as simple properties with a private setter. I did rewrite it with a readonly field behind.

Unfortunately, that didn't change anything nor did my conditional breakpoint ever fire. I even popped in a general one after it to make sure that I had set it up correctly. Granted, I had to comment out the unsubscribe to catch the error. Funny thing is, I don't even get a single MissingReferenceException from Unity (the exception that constantly fires when the game gets stuck in the loop) with the unsubscribe line, which I would expect to get one from the first pass of the bad Battle, even though I unsubscribe to it later. But, given your final point, I guess it makes sense, the MissingReferenceException means that I'm trying to use a reference to a Behaviour that was attached to an object that no longer exists.

Oh, I assumed you were getting null references. I don't know what MissingReferenceException is - it's some Unity thing, and I guess Unity uses a different resource model than vanilla .NET. (This doesn't surprise me, I'm just not familiar with it.)

quote:

Now, I should add something I just discovered from coming back to the code: I'm getting InvalidOperationExceptions from the following. Minor note: this is the CombatManager's Update method, which is called during every draw cycle for the Unity engine.
code:
// Note: curFights is a my List of Battles
// Only do stuff if will have active battles
if (curFights.Count == 0)
{
	return;
}

// Add the time to each battle
foreach (Battle temp in curFights)
{
	temp.AddTime (Time.deltaTime); // Time.deltaTime is how long it's been since the last Update call
}
Now, AddTime adds time to the timers for the two participants and tells them to attack, if enough time has passed. Now, if this attack leads to them being defeated they fire their DeathEvent, etc. I think this might be a cause of some problems, if not most of them. Just so that I'm understanding how events are handled, would this be a correct call stack if AddTime cause the death of a unit?

BattleCompleted - Listens for BattleEvent's from a Battle, does a curFights.remove(this Battle)
OnBattleCompleted - Fires a BattleEvent when a Battle completes, listens for DeathEvents
OnDeath - Fires a DeathEvent
TakeDamage - Called when a unit is attacked, fires OnDeath if health == 0
AddTime - Adds time to the battle timer, calls TakeDamage if enough time has passed
Update

I ask, because I assumed when designing this that events would be handled at the end of the current method call rather than what appears above. I now can see why this was a foolish assumption. I assume that I need to cull the list outside of BattleCompleted to stop this, which seems like a fun, little problem.

If you're trying to modify curFights while iterating it, you're definitely going to have problems. At this point, I'm not 100% clear on the relationship between participant death and battles ending, but you might consider breaking your single loop up into two (or even three) passes. First, loop through and apply damage, killing participants as necessary, but not triggering battle completion yet. Then, loop through again, completing battles with at least one dead participant. Then, cull resolved battles.

BirdOfPlay
Feb 19, 2012

THUNDERDOME LOSER

raminasi posted:

Oh, I assumed you were getting null references. I don't know what MissingReferenceException is - it's some Unity thing, and I guess Unity uses a different resource model than vanilla .NET. (This doesn't surprise me, I'm just not familiar with it.)

Sorry, I didn't want to get bogged down on Unity specifics but missed this one. Easiest way to think about it is with "has a" relationships, like a Body has a Hand. Unity sees that I'm trying to use something that exists as a part of something that has already been deleted and throws the exception. For example, trying to use a Hand when it's Body has been deleted.

quote:

If you're trying to modify curFights while iterating it, you're definitely going to have problems. At this point, I'm not 100% clear on the relationship between participant death and battles ending, but you might consider breaking your single loop up into two (or even three) passes. First, loop through and apply damage, killing participants as necessary, but not triggering battle completion yet. Then, loop through again, completing battles with at least one dead participant. Then, cull resolved battles.

Participant death has this flow, where "->" means it either directly calls a method or fires the event
Unit.TakeDamage -> Unit.DeathEvent -> Battle.UnitDeath -> Battle.BattleCompletedEvent -> CombatManage.BattleCompletion
It's funny, because a few weeks ago I was thinking: "You didn't know anything about events 6 months ago, and, now, you're just using them like it's natural. BirdOfPlay, you are one good coder." Now I kinda feel like I just got a hammer and, surprisingly, found a whole bunch of nails!

As far as how I solved it, I chose to keep as much of my existing flow in place and added another list to keep tabs on the Battles that needed to be culled. During the Unity draw loop, there's the option to run a method after everything else has been called LateUpdate, and that's where the culling happens.

Thanks for helping me work through this, rami. Even though some of this Unity stuff might've thrown you off a bit.

Sab669
Sep 24, 2009

Have any of you guys used third-party code analysis tools? My boss has me trying to compare the analyzer built into Visual Studio versus things like HP Fortify / IBM Security AppScan

All I can find is businesses-speak marketing bullshit. Can't find any actual reviews that tell me what they offer over the VS tool.

EssOEss
Oct 23, 2006
128-bit approved
The only static code analysis tool that has ever found any actual issues I cared about in my C# code was PVS Studio, so I was pretty impressed by that one - especially when it caught that good old "last line effect" in my code! Way too expensive to actually purchase, though. I am not going to pay 7000€ a year to remove some resource leak defects. VS builtin static analysis rules are garbage (trigger on some irrelevant nonsense only).

ReSharper code analysis was nice for some "newbie gotchas" when C# introduced lambdas and such - e.g. variable capture warnings -, though VS compiler warnings have caught up and these days I have thrown ReSharper onto the curb and use plain VS.

Of course, the lower the skill level of your developers, the more dumb mistakes they will make and so the tools will potentially have increased value.

No experience with HP or IBM tools but those company names already make me laugh - probably some "cover your rear end by warning on every little nugget" garbage.

EssOEss fucked around with this message at 14:26 on Oct 27, 2016

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

Sab669 posted:

Have any of you guys used third-party code analysis tools? My boss has me trying to compare the analyzer built into Visual Studio versus things like HP Fortify / IBM Security AppScan

All I can find is businesses-speak marketing bullshit. Can't find any actual reviews that tell me what they offer over the VS tool.

The only one I have experience with is SonarQube. The big difference is that it doesn't just do static code analysis, it does comprehensive technical debt analysis, including showing trends over time and helping you target the rule violations that are most critical so when you point it to a project with 50,000 violations, you don't just throw your hands up and say "well, nevermind then". Microsoft contributed a ton of code to the C# analyzer and Visual Studio plugin, so it's well-supported. It integrates into most build systems pretty easily, too.

It's also free so there's that.

Sab669
Sep 24, 2009

I'll check out Sonar, saw it mentioned a few times while trying to find anything to read in other tools. thanks.

chippy
Aug 16, 2006

OK I DON'T GET IT
I've got an async method that queries an API for a string result.

I've got a list of objects, and for each I want to asynchronously fire off a query to the API using this method, assign the result to a property on the object, and then await until I've got the response back for all of them before doing something else with the collection of objects.

What's the correct pattern for this? I'm looking at putting all the tasks in a collection and then Task.WhenAll to wait for all of them, which I've used before when I wasn't worried about using the results, but it returns an array of Task objects, and I'm not 100% sure about the ordering of this array and how to know which result belongs to which object.

The objects have unique Ids. I was thinking about creating a small class that just holds the id of the object and the string response, and returning that from my query method instead of just the string, then using those to map the responses back to the objects, but that feels a bit clumsy. Oh, I guess I could pass the object into the query method, and have IT update the object, rather than just returning the string.

I guess there are a few answers but I'd like to know what is 'best practice'.

chippy fucked around with this message at 17:18 on Oct 28, 2016

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

chippy posted:

I've got an async method that queries an API for a string result.

I've got a list of objects, and for each I want to asynchronously fire off a query to the API using this method, assign the result to a property on the object, and then await until I've got the response back for all of them before doing something else with the collection of objects.

What's the correct pattern for this? I'm looking at putting all the tasks in a collection and then Task.WhenAll to wait for all of them, which I've used before when I wasn't worried about using the results, but it returns an array of Task objects, and I'm not 100% sure about the ordering of this array and how to know which result belongs to which object.

The objects have unique Ids. I was thinking about creating a small class that just holds the id of the object and the string response, and returning that from my query method instead of just the string, then using those to map the responses back to the objects, but that feels a bit clumsy. Oh, I guess I could pass the object into the query method, and have IT update the object, rather than just returning the string.

I guess there are a few answers but I'd like to know what is 'best practice'.

Make a Dictionary<UniqueId, WhateverObject>. Task.WhenAll, then iterate through the Task collection, pull the object out of the dictionary, and update the object.

Or make everything immutable and save yourself the headache.

chippy
Aug 16, 2006

OK I DON'T GET IT

New Yorp New Yorp posted:

Make a Dictionary<UniqueId, WhateverObject>. Task.WhenAll, then iterate through the Task collection, pull the object out of the dictionary, and update the object.

Or make everything immutable and save yourself the headache.

I was thinking something like this, but how do I know which of the Tasks goes with which Dictionary item?

I'm guessing this is way easier than I'm making it and I'm just not thinking too clearly, I haven't done much async stuff, this is definitely not a last-thing-on-a-Friday type of problem. :)\

How would making everything immutable help?

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy
I wouldn't bother with a dictionary, you can just operate on the collection as normal. For example:

C# code:
var things = new List<Thing>(); // pretend there's stuff in it
var tasks = things.Select(async t => {
    var result = await DoAsyncThing(t);
    t.OtherThing = result;
    return t;
});
var newThings = await Task.WhenAll(tasks);
// newThings should be the same list as things
// since you're returning t in the above lambda
Doing it this way you can completely ignore ordering or lookups in a dictionary, since with the lambda in Select you're already operating on a single item in the collection, and can continue working with it after the async call.

Bognar fucked around with this message at 18:35 on Oct 28, 2016

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

Bognar posted:

I wouldn't bother with a dictionary, you can just operate on the collection as normal. For example:

C# code:
var things = new List<Thing>(); // pretend there's stuff in it
var tasks = things.Select(async t => {
    var result = await DoAsyncThing(t);
    t.OtherThing = result;
    return t;
});
var newThings = await Task.WhenAll(tasks);
// newThings should be the same list as things
// since you're returning t in the above lambda
Doing it this way you can completely ignore ordering or lookups in a dictionary, since with the lambda in Select you're already operating on a single item in the collection, and can continue working with it after the async call.

:doh: That's much cleaner.

Destroyenator
Dec 27, 2004

Don't ask me lady, I live in beer
How you want to deal with one or more network requests failing also matters.

ljw1004
Jan 18, 2005

rum

chippy posted:

I've got an async method that queries an API for a string result.
I've got a list of objects, and for each I want to asynchronously fire off a query to the API using this method, assign the result to a property on the object, and then await until I've got the response back for all of them before doing something else with the collection of objects.

What I'd love to see is (using C#7 tuples)

code:
var (name, address, tel) = await Task.WhenAll(
         obj.GetNameAsync(),
         obj.GetAddressAsync(),
         obj.GetTelAsync());

Calidus
Oct 31, 2011

Stand back I'm going to try science!

ljw1004 posted:


code:
var (name, address, tel) = await Task.WhenAll(
         obj.GetNameAsync(),
         obj.GetAddressAsync(),
         obj.GetTelAsync());

Welp now I am officially terrified of what I would see if my interns learn about tuples.

chippy
Aug 16, 2006

OK I DON'T GET IT

Bognar posted:

I wouldn't bother with a dictionary, you can just operate on the collection as normal. For example:

C# code:
var things = new List<Thing>(); // pretend there's stuff in it
var tasks = things.Select(async t => {
    var result = await DoAsyncThing(t);
    t.OtherThing = result;
    return t;
});
var newThings = await Task.WhenAll(tasks);
// newThings should be the same list as things
// since you're returning t in the above lambda
Doing it this way you can completely ignore ordering or lookups in a dictionary, since with the lambda in Select you're already operating on a single item in the collection, and can continue working with it after the async call.

That's neat, thanks very much.

chippy
Aug 16, 2006

OK I DON'T GET IT

chippy posted:

That's neat, thanks very much.

Actually this is causing all manner of insane weirdness. Stepping through, the debugger is somehow hitting BOTH the if and the else part of an if/else statement inside the async DoAsyncThing() method, and after watching t.OtherThing be populated with a value, it's back to being null again after awaiting all the tasks.

I'm just trying this with only one thing in the collection at the moment. It's like it's creating parallel universe copies of the objects when I do the select statement or something.

Anyone got any ideas? Otherwise I'm thinking I'm just going to abandon this, loop round the collection and await each API call in turn.

edit: I modified my code to be exactly the same pattern as yours (I had pulled the whole lambda out into its own method) and that seems to have stopped it from hitting the if/else in that crazy manner, but the required property is still null after awaiting all the tasks, after watching it quite clearly be populated in the lambda expression. There's only one object in the collection so I can't be looking at the wrong one. Are there some caveats with regards updating properties from different threads, or something?

chippy fucked around with this message at 12:30 on Oct 31, 2016

chippy
Aug 16, 2006

OK I DON'T GET IT
OK, my apologies for this one. In my code, the collection of things was an IEnumerable created by a LINQ statement. Seems like even after updating the properties, when I iterated the again collection after that, the LINQ statement was being re-run and recreating the collection with the null values.

I added a call to ToList() on things before doing any of the async stuff and everything works fine now.

However, when I go back to my original pattern of pulling out the whole lambda into a separate method, it seems to work fine, but the debugger seems to hit both parts of an if/else statement in the method. The else clause throws an exception, which isn't being caught by the try catch block wrapping the if else statement, so I *guess* the else clause isn't really being executed and the debugger is just stepping through it for some reason. Has anyone ever seen this?

tldr: The async stuff works fine now, but debugger steps through if AND else, seems to execute a throw statement in the else part, but no exception is caught, anyone know wtf this is?

chippy fucked around with this message at 13:04 on Oct 31, 2016

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy

chippy posted:

tldr: The async stuff works fine now, but debugger steps through if AND else, seems to execute a throw statement in the else part, but no exception is caught, anyone know wtf this is?

When the debugger hits in multiple places, I usually assume it's breaking on multiple threads of execution. However, if it doesn't seem like your else is actually being executed then the debug symbols could be incorrect, possibly? Are you building in release mode?

chippy
Aug 16, 2006

OK I DON'T GET IT

Bognar posted:

When the debugger hits in multiple places, I usually assume it's breaking on multiple threads of execution. However, if it doesn't seem like your else is actually being executed then the debug symbols could be incorrect, possibly? Are you building in release mode?

I did a bit of googling which suggested the Release mode thing but no, I'm building in Debug. It's a weird one. Still, it doesn't seem to be causing any problems.

sofokles
Feb 7, 2004

Fuck this
been googling and i only get the answer to the opposite.

passing a file name as a command line arg to a console app. ->args[0]

console.writeline'ing args[0] back to the console the extension is stripped.

how do I keep it ?

ive tried different variations of @ to no avail, and google only tells me about how to get rid of it. Also tried path.getextension(filename) from system.IO

app works fine when i hardcode the filename

sofokles
Feb 7, 2004

Fuck this

sofokles posted:

been googling and i only get the answer to the opposite.

passing a file name as a command line arg to a console app. ->args[0]

console.writeline'ing args[0] back to the console the extension is stripped.

how do I keep it ?

ive tried different variations of @ to no avail, and google only tells me about how to get rid of it. Also tried path.getextension(filename) from system.IO

app works fine when i hardcode the filename

You Sir, are an Idiot.

Were you absent from the class on double quotes?

sofokles
Feb 7, 2004

Fuck this

sofokles posted:

You Sir, are an Idiot.

Were you absent from the class on double quotes?

doublequoting

SirViver
Oct 22, 2008
I realize this might be more of a Visual Studio/Roslyn(?) question than being directly C#/.NET related, but has anyone here dabbled with writing of custom debugger visualizers? Or more specifically, knows how VS (or the .NET runtime?) determines whether an object is "replaceable" or not?

The reason I'm asking is that I have two generally working visualizers, one for DataSets and one for strings, but ever since I switched to Visual Studio 2015 (which is why I'm suspecting Roslyn) the visualizer for strings does not allow me to in-place edit them anymore (i.e., IVisualizerObjectProvider.IsObjectReplaceable = false). Clearly, strings are generally editable during debugging or otherwise you couldn't edit them in-line (using the "hover-watch" or watch window), but for some reason the debugger visualizers don't get access to that functionality anymore.

I mean, it's not a huge deal, but sometimes it would be nice to be able to edit large strings containing newlines in a proper editor than in a single enormous line :)

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



I'm trying to hit an IISExpress site from a device emulator and followed http://stackoverflow.com/a/18958879/301807 to try to get it working. Now when I try to start the project, it complains that the start URL is invalid. Should I just give up and use IIS or is there some trick to getting this stupid thing to work right?

Also, why the hell isn't there a 'Let Other Machines Connect to This Project (warning: security risk)' checkbox or something similar? Can nobody at MS conceive of the notion that I might want to get feedback on my work without deploying to a remote server or running VS as Admin full-time?

E: FFS IIS won't even run this thing :(

Munkeymon fucked around with this message at 19:36 on Nov 3, 2016

chippy
Aug 16, 2006

OK I DON'T GET IT
Anyone ever else feel like for all the time Entity Framework saves you, every now and then it just turns round and takes it all back with a day or two of inexplicable bullshit?

Baloogan
Dec 5, 2004
Fun Shoe
Yup, I've given up on EF. Its too much bother when its having a bad day.

chippy
Aug 16, 2006

OK I DON'T GET IT

chippy posted:

Anyone ever else feel like for all the time Entity Framework saves you, every now and then it just turns round and takes it all back with a day or two of inexplicable bullshit?

To elaborate on this:

I recently read on a blog about how you could mark setters and contructors private and EF was still able to use them via reflection to populate our entities: http://thedatafarm.com/data-access/entity-framework-private-constructors-and-private-setters/

I just tried this out and everything seemed to work fine except for one thing. When I marked the zero-argument constructor of Foo as 'private' everything seemed to work fine, except it broke lazy loading on a collection of Bar's held by Foo. It's just taken me an hour or two of trial and error to pinpoint that as the cause.

Does anyone know why this is?

edit: To be fair, there a bunch of people mentioning this in the comments of that blog piece, so I guess I only have myself to blame for not reading properly.

chippy fucked around with this message at 12:40 on Nov 4, 2016

Horn
Jun 18, 2004

Penetration is the key to success
College Slice

chippy posted:

Anyone ever else feel like for all the time Entity Framework saves you, every now and then it just turns round and takes it all back with a day or two of inexplicable bullshit?

This is my feeling as well. My take is that for small projects you won't run into issues but it doesn't buy you a lot then and for larger projects you are going to end up fighting it unless your model fits in with EF perfectly.

I just roll with dapper 90% of the time now.

chippy
Aug 16, 2006

OK I DON'T GET IT
I miss working with Dapper actually. Unfortunately the project I'm working on currently already used EF so I had to roll with it.

OK, another async question for me.

Why can't I do this?

code:
public async Task<Foo> DoAThing(Bar aBar)
{
	// some async work with awaits and stuff that makes a Baz called baz eventually

	[b]return DoARelatedThing(aBar, baz);[/b]
}

public async Task<Foo> DoARelatedThing(Bar aBar, Baz aBaz)
{
	// some async work with awaits and stuff that creates a Foo called foo eventually

	return foo;
}
On the bolded call, I get the compiler error "Since this is an async method, the return expression must be of type 'Foo' rather than Task<Foo>'. I have to add an await to the return to make it 'return await DoARelatedThing(aBar, baz)'. I don't understand why. Both methods return the same type, so why can't DoAThing just return the result of DoARelatedThing?

Red Mike
Jul 11, 2011

chippy posted:

I miss working with Dapper actually. Unfortunately the project I'm working on currently already used EF so I had to roll with it.

OK, another async question for me.

Why can't I do this?
[/code]

On the bolded call, I get the compiler error "Since this is an async method, the return expression must be of type 'Foo' rather than Task<Foo>'. I have to add an await to the return to make it 'return await DoARelatedThing(aBar, baz)'. I don't understand why. Both methods return the same type, so why can't DoAThing just return the result of DoARelatedThing?

When you mark a function as async, you are essentially telling the function that your return type is X, when your defined return type is Task<X>. The correct way to do what you want is this:

code:
public Task<Foo> DoAThing(Bar aBar)
{
	// some async work with awaits and stuff that makes a Baz called baz eventually

	[b]return DoARelatedThing(aBar, baz);[/b]
}

public async Task<Foo> DoARelatedThing(Bar aBar, Baz aBaz)
{
	// some async work with awaits and stuff that creates a Foo called foo eventually

	return foo;
}
This will do what you expect, however you will be unable to use awaits in DoAThing. It does however mean that DoAThing is an async wrapper of an async method, that doesn't have to await at any point, and the compiler won't complain about it running synchronously since it does.

This doesn't strictly answer your question since I don't know exactly why you can't just do this, but it took me a while to realise you can combine async/non-async like this and potentially you might not have realised either.

NiceAaron
Oct 19, 2003

Devote your hearts to the cause~

If you want to keep the first method as async, this should work:

code:
public async Task<Foo> DoAThing(Bar aBar)
{
	// some async work with awaits and stuff that makes a Baz called baz eventually

	return await DoARelatedThing(aBar, baz);
}

public async Task<Foo> DoARelatedThing(Bar aBar, Baz aBaz)
{
	// some async work with awaits and stuff that creates a Foo called foo eventually

	return foo;
}
Basically, you need to tell DoAThing to wait for the task returned by DoARelatedThing to finish and use the result value. Otherwise you're working with the Task object itself instead of the result value.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy
You've probably got it by now, but I wanted to distill it down. If you have an async method and you return a Foo, the return type of the method is Task<Foo>. You have an async method and are trying to return a Task<Foo>, so the compiler expects the return type of the first method to be Task<Task<Foo>>.

As the other responses have already shown, in an async method to get a Foo out of a Task<Foo>, you have to await the task.

Pixelboy
Sep 13, 2005

Now, I know what you're thinking...

Sab669 posted:

Have any of you guys used third-party code analysis tools? My boss has me trying to compare the analyzer built into Visual Studio versus things like HP Fortify / IBM Security AppScan

All I can find is businesses-speak marketing bullshit. Can't find any actual reviews that tell me what they offer over the VS tool.

What version of VS? VS2015 has good analysis tools, but you can extend it with all sorts of really great Roslyn analyzers.

If you want to shell out, Resharper is good.

Hughmoris
Apr 21, 2007
Let's go to the abyss!
New to C# (have dabbled in Python and Perl). I am making a request to the RottenTomatoes API, and I end up with a string in JSON format. The string is essentially an array of dictionaries, full of movies. Example here: http://pastebin.com/CsbTNGqX

What would be the best way to iterate through each array element, printing out the movie title? Should I convert the string to a JSON object, and then try to work with that?

Hughmoris fucked around with this message at 01:15 on Nov 5, 2016

raminasi
Jan 25, 2005

a last drink with no ice

Hughmoris posted:

New to C# (have dabbled in Python and Perl). I am making a request to the RottenTomatoes API, and I end up with a string in JSON format. The string is essentially an array of dictionaries, full of movies. Example here: http://pastebin.com/CsbTNGqX

What would be the best way to iterate through each array element, printing out the movie title? Should I convert the string to a JSON object, and then try to work with that?

Yeah, define .NET types to mirror the structure of the JSON and then use Json.NET to convert it.

Hughmoris
Apr 21, 2007
Let's go to the abyss!

raminasi posted:

Yeah, define .NET types to mirror the structure of the JSON and then use Json.NET to convert it.

I just had my mind blow.

As mentioned, I'm extremely new to the language so I was trying to figure out how to create classes and properties to exactly mirror the structure of my JSON-formatted string, and I was flailing. I hopped on the ##csharp channel and someone told me about Visual Studios "edit -> paste special -> paste JSON as classes".

Coming from scratching the surface of Vim, that is seriously some magical poo poo. It created all of the classes and properties exactly as they needed to be, and my program worked.

Hughmoris fucked around with this message at 04:38 on Nov 5, 2016

raminasi
Jan 25, 2005

a last drink with no ice

Hughmoris posted:

I just had my mind blow.

As mentioned, I'm extremely new to the language so I was trying to figure out how to create classes and properties to exactly mirror the structure of my JSON-formatted string, and I was flailing. I hopped on the ##csharp channel and someone told me about Visual Studios "edit -> paste special -> paste JSON as classes".

Coming from scratching the surface of Vim, that is seriously some magical poo poo. It created all of the classes and properties exactly as they needed to be, and my program worked.

Oh yeah I forgot about that. You can do it with XML too, if it ever comes up.

chippy
Aug 16, 2006

OK I DON'T GET IT
Thanks for the 'return await' explanation earlier chaps, makes sense now.

Adbot
ADBOT LOVES YOU

Combat Pretzel
Jun 23, 2004

No, seriously... what kurds?!
Those Telerik guys must have a really hard time to get by. A long while ago, I've downloaded one of their UI component libraries to get a very old project up and running to check out some things. Since then, some sales guy is pestering me with at least one e-mail per week.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply