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
The Gripper
Sep 14, 2004
i am winner
So I'm using F# as part of a project and haven't had a lot of experience with mixing mutable and immutable elements in a functional language, can anyone recommend any decent reading material on pros/cons/best-practices for this? A lot of general papers make the assumption that everything should be immutable at any cost and the resulting code tends to avoid anything mutable even if it's available (and seemingly has a good use in the situation).

Basically I'm writing things like this to cache data
code:
let whatever =
   let cache = new Dictionary<_,_>()
   let rec _whatever n =
      if cache.ContainsKey(n) then cache.[n]
      elif ...
         ...
         cache.Add(n,result)
         result
      else
         "None"
   fun n -> _whatever n
and don't know if this is bad form and could cause problems in a larger project, even though as far as I'm concerned this is working, faultless code that meets requirements currently.

The Gripper fucked around with this message at 13:25 on Mar 9, 2012

Adbot
ADBOT LOVES YOU

aBagorn
Aug 26, 2004
Ithaqua, that code worked, by the way.

Talking with this Java guy is actually helping me much more than I thought.

He keeps asking me "can LINQ do this? how would you do that?" and I'm trial and erroring my way through his questions and learning stuff I wouldn't have thought of.

Sedro
Dec 31, 2008
WPF binding path question:
code:
MyProperty="{Binding First.Second.Third, Mode=OneWay}"
I think this will listen for PropertyChanged on First, Second and Third. How do you use a different mode for each step in the path? For example:
code:
MyProperty="{Binding First(OneWay).Second(OneTime).Third(OneTime)}"

Sedro
Dec 31, 2008
Another question. I'm basically doing this:
code:
<ListBox
    SelectionMode="Extended"
    VirtualizingStackPanel.IsVirtualizing="True"
    ItemsSource="{Binding ..., Mode=OneTime}"
    >
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Image Source="{Binding ..., Mode=OneWay}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>
If I have 1000 items in the list, and 20 items in the virtualized view, I would expect ~20 images to be loaded at any one time. Instead, if I scroll through the list, it loads all 1000 images into memory and never releases them (judging by the 300MB of increased memory usage). These are ~30KB images on disk (much bigger as in-memory bitmaps).

I've tried various ways of binding to the image: binding to a path, using a converter which loads from a stream/URI, etc.

Edit: I guess I could create my own Image control (or attached property) which does visibility testing and unloads the image if not visible. Or take advantage of the virtualizing panel instead of visibility testing.

Edit2: The images were ~300x300 when I really only needed 32x32, so setting the DecodePixel(Width/Height) brought the memory down to something manageable. I would still be SOL though if I needed a list of larger images.

Sedro fucked around with this message at 21:25 on Mar 9, 2012

boo_radley
Dec 30, 2005

Politeness costs nothing
A testimonial for for extension methods and refactoring (and also my saint-like patience with my coworkers)

Working through some refactoring with my coworkers today and explaining how to use delegates and collections, turning

code:
foreach (person p in people)
{
   massage(p);
}
to
code:
people.ForEach(p => massage(p));
where massage is a refactored method that used to be 100 lines in the foreach loop.

We come to a data input function, which has this at its heart:
code:
 using (TextReader tr = File.OpenText(ConfigurationManager.AppSettings["inputfile"]))
      {
        string thisRec;
        while (null != (thisRec = tr.ReadLine()))
        {
          boop(thisRec);
        }
      }
and his question is "where's the foreach for the textreader? That would simplify things a whole bunch!" So we talk extension methods:

code:
public static class Extensions
  {
    public delegate void TextReaderAction(string line);
    public static void ForEach(this TextReader tr, TextReaderAction tra)
    {
      string line; 
      while (null != (line = tr.ReadLine()))
      {
        tra(line);
      }
    }
  }
and sure enough, it works as expected and all our data boop correctly.
code:
tr.ForEach(line => boop(line));
then ReSharper pipes up:


and now this alone works:
code:
tr.ForEach(Boop);
My tools amaze me sometimes and I get the feeling no matter how much I apply myself, I'll only ever know a tiny fraction of what I can do in this language.

Mr.Hotkeys
Dec 27, 2008

you're just thinking too much

boo_radley posted:

code:
foreach (person p in people)
{
   massage(p);
}
to
code:
people.ForEach(massage);

Other than readability is there any advantage to this?

Sedro
Dec 31, 2008
Here's the implementation of ForEach:
code:
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
    foreach (var item in source)
        action(item);
}
So no.

You could even chain side effects along with your transformations:
code:
public static IEnumerable<T> Do<T>(this IEnumerable<T> source, Action<T> action)
{
    foreach (var item in source)
    {
        action(item);
        yield return item;
    }
}

public static void Evaluate<T>(this IEnumerable<T> source)
{
    foreach (var item in source) ;
}

foo.Select(f => f.Whatever)
   .Where(w => w.Count > 0)
   .Do(w => { w.MyEvent += MyEventHandler; })
   .Evaluate();
I would argue that it's less readable, because it's unclear whether a method is evaluating the collection or if it's a linq tunnel, or if it has any side effects.

Zhentar
Sep 28, 2003

Brilliant Master Genius

Mr.Hotkeys posted:

Other than readability is there any advantage to this?

Compile time type checking. If people isn't an IEnumerable<person>, the foreach( x in y) will throw a cast exception at run time, while the .ForEach(action) will raise a compile error about the overload resolution (assuming, of course, there's not an action overload that matches what people does contain).

boo_radley
Dec 30, 2005

Politeness costs nothing

Mr.Hotkeys posted:

Other than readability is there any advantage to this?

For us, the benefit was more in refactoring the work done in the foreach loop than conversion of the loop. We have a few crusty old VB6 and classic ASP programmers who haven't kept fresh and I'm trying to show them how to be a bit more mindful about how they program and use the features that have come in the years since they started.

raminasi
Jan 25, 2005

a last drink with no ice
I've got a WPF application that does a few relatively time-consuming things. Some of them are dependent upon others but they aren't all necessarily needed and I need to keep the UI responsive while they run. How should I be structuring this? What I've got thrown together at present is having them all take as a parameter an executeNext action. When each runs, it checks its dependencies, and if it's missing one it fires that one asynchronously (via BackgroundWorkers) with itself as the executeNext and then returns. This, while working, feels very, very wrong (and won't work as soon as my dependency graph gets even a little bit complicated, which it might). I feel like there might be a magic bullet in the Async CTP, but I don't know how to get it to play with WPF and BackgroundWorkers. As an added wrinkle, each of these long-running tasks updates the UI indirectly via ReportProgress (just status messages) and I don't know how async stuff would deal with that.

raminasi fucked around with this message at 23:29 on Mar 9, 2012

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

GrumpyDoctor posted:

I've got a WPF application that does a few relatively time-consuming things. Some of them are dependent upon others but they aren't all necessarily needed and I need to keep the UI responsive while they run. How should I be structuring this? What I've got thrown together at present is having them all take as a parameter an executeNext action. When each runs, it checks its dependencies, and if it's missing one it fires that one asynchronously (via BackgroundWorkers) with itself as the executeNext and then returns. This, while working, feels very, very wrong (and won't work as soon as my dependency graph gets even a little bit complicated, which it might). I feel like there might be a magic bullet in the Async CTP, but I don't know how to get it to play with WPF and BackgroundWorkers. As an added wrinkle, each of these long-running tasks updates the UI indirectly via ReportProgress (just status messages) and I don't know how async stuff would deal with that.

Post some code. With the async CTP, you wouldn't need background workers at all.

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

boo_radley posted:

We have a few crusty old VB6 and classic ASP programmers who haven't kept fresh and I'm trying to show them how to be a bit more mindful about how they program and use the features that have come in the years since they started.

Ugh. In my experience, those guys are the worst, because they haven't been keeping up in the first place since they don't care. If they don't care about keeping up with the skills they need to succeed in their career, they don't care about the code they write.

My last job was like that. They just wrote the same crappy code and then bitched at me for "wasting time" refactoring and writing unit tests. The unit tests almost always uncovered horrible bugs and corner cases, too.

Sedro
Dec 31, 2008

GrumpyDoctor posted:

I've got a WPF application that does a few relatively time-consuming things.
You can probably use the same patterns and have much cleaner code just by using TPL instead of BackgroundWorkers. It's easy for tasks to wait on the result of other tasks. Async CTP is just a nice abstraction for this.

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!
Is there a way to access or at least copy a file that's in use at runtime?

I'm trying to use the OpenXML API, but Word locks files while they're in use. Windows doesn't seem to have any difficulty copying them, but accessing them from an application has explosive results.

raminasi
Jan 25, 2005

a last drink with no ice

Ithaqua posted:

Post some code. With the async CTP, you wouldn't need background workers at all.

code:
void PerformLongTaskA(LongTaskAParams params, Action executeNext)
{
    if (longTaskBResults == null)
    {
        // long task B hasn't been run
        PerformLongTaskB(ConstructNewLongTaskBParamsSomehow(), PerformLongTaskA);
        return;
    }
    longTaskAWorker.RunWorkerAsync(Tuple.Create(params, executeNext));
}

void longTaskAWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    longTaskAResults = (LongTaskAResults)e.Result;
    longTaskAResults.ExecuteNext(); // in reality executeNext is in a different structure but whatever
}
I'm totally down with ditching BackgroundWorkers, but how do I let my long tasks update the UI if they're in a different thread? In this case the actual code in longTaskAWorker_DoWork calls longTaskAWorker.ReportProgress.

PhonyMcRingRing
Jun 6, 2002
Anyone know if there's an inherent performance difference between using OleDb in a console application and using it in a WebForms app? More details here: http://stackoverflow.com/questions/9641821/varying-oledb-performance

PhonyMcRingRing
Jun 6, 2002

Zhentar posted:

Compile time type checking. If people isn't an IEnumerable<person>, the foreach( x in y) will throw a cast exception at run time, while the .ForEach(action) will raise a compile error about the overload resolution (assuming, of course, there's not an action overload that matches what people does contain).

I'm not sure what additional compile time checking you'd get out of this. A foreach over an IEnumerable<person> is going to guarantee that each object is of type person. Now if you're iterating over a non-generic IEnumerable, that'd be a problem seeing as you have to cast each object, but a ForEach extension method isn't gonna help you there anyway.

Jetsetlemming
Dec 31, 2007

i'Am also a buetifule redd panda

Sedro posted:

WPF binding path question:
code:
MyProperty="{Binding First.Second.Third, Mode=OneWay}"
I think this will listen for PropertyChanged on First, Second and Third. How do you use a different mode for each step in the path? For example:
code:
MyProperty="{Binding First(OneWay).Second(OneTime).Third(OneTime)}"
I don't know about your mode question, but in order for a PropertyChanged to work both the wpf element has to be listening, and the bound property has to be broadcasting. You could make your Second and Third items just not trigger a PropertyChanged event, or if you need that elsewhere, make extra Properties that get/set from them, and have those Properties not trigger the event.

Sedro
Dec 31, 2008

PhonyMcRingRing posted:

Now if you're iterating over a non-generic IEnumerable, that'd be a problem seeing as you have to cast each object, but a ForEach extension method isn't gonna help you there anyway.
You could have it do the cast.
code:
public static void ForEach<T>(this IEnumerable source, Action<T> action)
{
    foreach (T item in source)
        action(item);
}

nonGenericList.ForEach<string>(...);

ljw1004
Jan 18, 2005

rum

GrumpyDoctor posted:

I'm totally down with ditching BackgroundWorkers, but how do I let my long tasks update the UI if they're in a different thread?

Read about the new "Task Asynchronous Pattern" - http://www.microsoft.com/download/en/details.aspx?id=19957
Everything I'm writing here assumes you're either using VS11 beta which supports TAP natively and has a go-live license, or using VS2010 with the AsyncCTP. The AsyncCTP is just a tech-preview and a bit awkward to install.


First thing: is the background-work CPU-intensive? or is it just long-running because it's blocked by other stuff such as disk or network?

You should put CPU-intensive work on a background thread, e.g.
code:
Task t = Task.Run(delegate { ...compute-bound work...} );
...
// and later on, when you need to know that it's finished,
await t;
In this case the body of the delegate gets run on the background thread, but the rest of the code remains on the UI thread. You still need a way for the body of the delegate to update the UI. I'll get to that later.


You shouldn't use background threads for IO operations. Instead use "await" for them, e.g.
code:
Task<string> t = new WebClient().DownloadStringAsync(url);
string result = await t;
In this case none of your code has even left the UI thread. That means you can update the UI just fine.




Use IProgress<T> to report progress. Here's a full-blown example of a function that combines progress-reporting with cancellability.
code:
async Task FredAsync(IProgress<int> progress, CancellationToken cancel)
{
    for (int i = 0; i < 10000; i++)
    {
        cancel.ThrowIfCancellationRequested();
        progress.Report(i);
        // ... do the actual compute work
    }
}


var cts = new CancellationTokenSource();
var progress = new Progress<int>((i) => TextBox1.Text = i.ToString());
await FredAsync(progress, cts.Token);
In your code, I wasn't clear what you were trying to do because I got lost in the completion-delegates. But it looked like you were implementing nothing more than this...
code:
Task<BResults> longTaskB;

async Task<AResult> DoItAll(AParams params)
{
   var bresults = await longTaskB;
   var aresults = await DoLongTaskA();   
   return aresults;
}
Of course, you'd add on IProgress<T> and CancellationToken parameters as needed to DoItAll and DoLongTaskA. You might write a Button1_Click event-handler which does "cts.Cancel()", to cancel it all.

raminasi
Jan 25, 2005

a last drink with no ice
Bingo, this is exactly what I was looking for. Thanks!

ljw1004 posted:

Read about the new "Task Asynchronous Pattern" - http://www.microsoft.com/download/en/details.aspx?id=19957
Everything I'm writing here assumes you're either using VS11 beta which supports TAP natively and has a go-live license, or using VS2010 with the AsyncCTP. The AsyncCTP is just a tech-preview and a bit awkward to install.
I'm going to have to use the AsyncCTP. What's difficult about the installation? And is the license different?

quote:

First thing: is the background-work CPU-intensive? or is it just long-running because it's blocked by other stuff such as disk or network?

You should put CPU-intensive work on a background thread, e.g.
code:
Task t = Task.Run(delegate { ...compute-bound work...} );
...
// and later on, when you need to know that it's finished,
await t;
In this case the body of the delegate gets run on the background thread, but the rest of the code remains on the UI thread. You still need a way for the body of the delegate to update the UI. I'll get to that later.
Some of them are CPU-bound and some of them are I/O-bound.

quote:

You shouldn't use background threads for IO operations. Instead use "await" for them, e.g.
code:
Task<string> t = new WebClient().DownloadStringAsync(url);
string result = await t;
In this case none of your code has even left the UI thread. That means you can update the UI just fine.
Oh, ok, they're technically I/O-bound but they're still my own contraptions and they can barf just as many status updates as the CPU-bound ones, so I guess I have to treat them that way.

quote:

Use IProgress<T> to report progress. Here's a full-blown example of a function that combines progress-reporting with cancellability.
code:
async Task FredAsync(IProgress<int> progress, CancellationToken cancel)
{
    for (int i = 0; i < 10000; i++)
    {
        cancel.ThrowIfCancellationRequested();
        progress.Report(i);
        // ... do the actual compute work
    }
}

var cts = new CancellationTokenSource();
var progress = new Progress<int>((i) => TextBox1.Text = i.ToString());
await FredAsync(progress, cts.Token);
:swoon:

quote:

In your code, I wasn't clear what you were trying to do because I got lost in the completion-delegates. But it looked like you were implementing nothing more than this...
code:
Task<BResults> longTaskB;

async Task<AResult> DoItAll(AParams params)
{
   var bresults = await longTaskB;
   var aresults = await DoLongTaskA();   
   return aresults;
}
Of course, you'd add on IProgress<T> and CancellationToken parameters as needed to DoItAll and DoLongTaskA. You might write a Button1_Click event-handler which does "cts.Cancel()", to cancel it all.
Yeah, I wasn't reinventing anything complicated, but I could tell that I was reinventing something so I figured I should try to find out what that was.

PhonyMcRingRing
Jun 6, 2002

Sedro posted:

You could have it do the cast.
code:
public static void ForEach<T>(this IEnumerable source, Action<T> action)
{
    foreach (T item in source)
        action(item);
}

nonGenericList.ForEach<string>(...);

Right, but it wouldn't compile-time guarantee that the IEnumerable is IEnumerable<T>.

Sedro
Dec 31, 2008

Jetsetlemming posted:

I don't know about your mode question, but in order for a PropertyChanged to work both the wpf element has to be listening, and the bound property has to be broadcasting. You could make your Second and Third items just not trigger a PropertyChanged event, or if you need that elsewhere, make extra Properties that get/set from them, and have those Properties not trigger the event.
There was a bug at one point where binding OneWay on an object which didn't implement INPC would cause a memory leak. I think that's fixed now, but I still like binding OneTime if I know the property won't change.

ljw1004
Jan 18, 2005

rum

GrumpyDoctor posted:

I'm going to have to use the AsyncCTP. What's difficult about the installation? And is the license different?

License: AsyncCTP is "as is" license, meaning you can use it in production code but it's not supported. VS11-Beta is "go live" license, meaning it is.

Installation: The AsyncCTP was done as a patch to VS2010 but was never part of the actual main code. Periodically, new patches come out for VS2010; if they're present and they touch the same files as the AsyncCTP then the AsyncCTP can't be installed.

raminasi
Jan 25, 2005

a last drink with no ice
So, uh, I tried to install the Async CTP, and the installer ran correctly, but I can't figure out what it actually installed. There's no "Microsoft Visual Studio Async CTP" folder in My Documents.

edit: ok apparently I have some Visual Studio update that makes this not work. Am I just SOL?

edit 2: I guess I have to install this on top of a fresh Visual Studio SP1, but you can't remove SP1 without completely reinstalling Visual Studio. ughhhhhh

raminasi fucked around with this message at 23:52 on Mar 10, 2012

ljw1004
Jan 18, 2005

rum

GrumpyDoctor posted:

So, uh, I tried to install the Async CTP, and the installer ran correctly, but I can't figure out what it actually installed. There's no "Microsoft Visual Studio Async CTP" folder in My Documents.

edit: ok apparently I have some Visual Studio update that makes this not work. Am I just SOL?

edit 2: I guess I have to install this on top of a fresh Visual Studio SP1, but you can't remove SP1 without completely reinstalling Visual Studio. ughhhhhh

Yes, if there's no "MS VS Async CTP" folder in My Documents then the installer failed.

One approach is to uninstall the particular updates that get in the way, then install AsyncCTP, then reinstall the updates. The two most recent update culprits that I know of are KB2635973 and KB2615527.


(Sorry it's such a bad experience. We don't have divisional experience in releasing and supporting a CTP for 18+ months, and didn't understand at first how bad the updates would be, and are unwilling to devote much resources to the CTP when we'd rather be working on Dev11. We're working on a plan so it's easier for Dev11 to use async when targetting .NET4/SL5.)

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug
Unfortunately, the async CTP is pretty firmly in the "fun to play with, shouldn't use in a production environment" category. Luckily, VS11 will be out soonish!

Zhentar
Sep 28, 2003

Brilliant Master Genius

PhonyMcRingRing posted:

I'm not sure what additional compile time checking you'd get out of this. A foreach over an IEnumerable<person> is going to guarantee that each object is of type person. Now if you're iterating over a non-generic IEnumerable, that'd be a problem seeing as you have to cast each object, but a ForEach extension method isn't gonna help you there anyway.

What makes you so sure people is an IEnumerable<person>? Nothing in the code snippet says that. people could be an IEnumerable<int> and you still won't even get a compiler warning. With foreach, you're casting whether you intend to or not.

Huragok
Sep 14, 2011
I have a MVC project that has the capability to be very memory hungry. Basically, I have a persistent object (serializable) that I need to limit memory usage for. AFAIK there's no way to limit the memory consumption of a task/thread. I've tried running it in a separate AppDomain, but I can't seem to get that object to persist.

Should I spin this persistent object/process off into a separate process and limit the subprocess's allocated memory? My guess is yes, but I just wanted to see if anyone else had some experience in this before I commit to a major chunk of time.

Sedro
Dec 31, 2008
Are you expecting memory to steadily grow until you run out and crash?

npe
Oct 15, 2004

Zhentar posted:

What makes you so sure people is an IEnumerable<person>? Nothing in the code snippet says that. people could be an IEnumerable<int> and you still won't even get a compiler warning. With foreach, you're casting whether you intend to or not.

Huh? I'm not sure what you are trying to say, because this won't compile:

code:
            IEnumerable<string> strings = new string[0];

            foreach (int x in strings)
            {
            }

Huragok
Sep 14, 2011

Sedro posted:

Are you expecting memory to steadily grow until you run out and crash?

No. It's dependent on user activity. It's a JavaScript engine that can't limit it's own memory usage. I want to prevent one user from gobbling-up all the memory and making the app fall over.

Atimo
Feb 21, 2007
Lurking since '03
Fun Shoe

Zhentar posted:

What makes you so sure people is an IEnumerable<person>? Nothing in the code snippet says that. people could be an IEnumerable<int> and you still won't even get a compiler warning. With foreach, you're casting whether you intend to or not.



Go read the spec.

http://msdn.microsoft.com/en-us/library/ms228593.aspx

Section 8.8.4

Zhentar
Sep 28, 2003

Brilliant Master Genius

npe posted:

Huh? I'm not sure what you are trying to say, because this won't compile:

code:
            IEnumerable<string> strings = new string[0];

            foreach (int x in strings)
            {
            }

Oops, I guess I was too broad there; it does ensure that a conversion does exist. It is still a cast, though, so you can still run into problems if you change the type of the collection you're enumerating (and I know that for a fact because I learned it the hard way).

uXs
May 3, 2005

Mark it zero!

Ithaqua posted:

Unfortunately, the async CTP is pretty firmly in the "fun to play with, shouldn't use in a production environment" category. Luckily, VS11 will be out soonish!

Eh, we're using it and it's cool. We're pretty small though, maybe it's more of a hassle otherwise.

The Gripper
Sep 14, 2004
i am winner

uXs posted:

Eh, we're using it and it's cool. We're pretty small though, maybe it's more of a hassle otherwise.
It's typically fine with a clean install (without previous async CTP installs), but going from the first CTP to the refresh can be painful (msdn dev blog says it could take > 2hrs to uninstall+install new CTP if there's any issue). A lot of people only got started it with the async CTP Refresh (early April 2011) so they luckily got to skip the upgrade mess.

Also there are changes to async/await between the CTP and the VS11 Beta - some breaking - that may cause problems migrating from the CTP to 11 (I don't know if any of the changes will affect distributing CTP-compiled applications though).

See also: http://msmvps.com/blogs/jon_skeet/archive/2012/01/12/eduasync-part-18-changes-between-the-async-ctp-and-the-visual-studio-11-preview.aspx

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

Huragok posted:

No. It's dependent on user activity. It's a JavaScript engine that can't limit it's own memory usage. I want to prevent one user from gobbling-up all the memory and making the app fall over.

What do you want to happen when one user consumes all of their allotted memory?

Huragok
Sep 14, 2011

Jabor posted:

What do you want to happen when one user consumes all of their allotted memory?

Either suspend or kill it.

npe
Oct 15, 2004

Huragok posted:

Either suspend or kill it.

Killing a thread is not an inherently safe thing to do. If you want to be able to safely monitor and kill it, I think you're going to need a separate process.

If it helps, I've been mired by this problem before and solved it by using the MAF framework (http://msdn.microsoft.com/en-us/library/bb384200.aspx) which allowed me to run the code I didn't trust in a completely different process, so I could keep an eye on memory usage and then just outright kill the thing if I needed to. Unfortunately getting it to work involved quite a lot of boilerplate, but it did end up working very well.

(Also, I think it was someone here who recommended MAF to begin with, so thanks for that. :))

Adbot
ADBOT LOVES YOU

Huragok
Sep 14, 2011

npe posted:

Killing a thread is not an inherently safe thing to do. If you want to be able to safely monitor and kill it, I think you're going to need a separate process.

Well right now, users can kill their thread at will. I spin up a new thread when that happens which removes any reference to the old execution context and then force a collection. Haven't profiled it yet, but everything seems to be fine :shobon:

npe posted:

If it helps, I've been mired by this problem before and solved it by using the MAF framework (http://msdn.microsoft.com/en-us/library/bb384200.aspx) which allowed me to run the code I didn't trust in a completely different process, so I could keep an eye on memory usage and then just outright kill the thing if I needed to. Unfortunately getting it to work involved quite a lot of boilerplate, but it did end up working very well.

(Also, I think it was someone here who recommended MAF to begin with, so thanks for that. :))

Looks complex. It I'll give it a read. Thanks!

  • Locked thread