1

I've got the following task which will run occasionally and utilize externally provided resources.

// start receiving the data
receiving = Task.Run(() =>
{
    string dataCopy = string.Empty;
    string next = string.Empty;

    while (true)
    {
        next = this.buffer.Take(t);

        if(!string.IsNullOrEmpty(next))
        {
            // keep appending the data
            dataCopy += next;

            // check if we've gotten the EOL
            if(dataCopy.Contains(endOfLine))
            {
                // remove the EOL
                dataCopy = this.lib.RemoveString(dataCopy, endOfLine);
                break;
            }
        }

        t.ThrowIfCancellationRequested();
    }

    return dataCopy;
}, t);

My intent here is to have the task cancel immediately when another thread pulls the trigger on the CancellationTokenSource. Which, seeing as the task spends most of its time sitting on buffer (which is of type BlockingCollection) the task will most likely cancel immediately when .Take throws its exception.

Now here is my concern... on the off-chance that the task is executing somewhere between the .Take method call but before the this.lib.RemoveString call... The lib object is an externally provided resource and as such will be disposed of externally (hopefully after this thread is done executing).

What's to say that my code won't one day throw an ObjectDisposedException on trying to call the RemoveString method? How can I safeguard against that scenario?

Snoop
  • 1,046
  • 1
  • 13
  • 33
  • You can't. Even if there is a `lib.IsDisposed` , its use wouldn't be thread-safe. – H H Oct 18 '17 at 18:54
  • _"hopefully after this thread ..."_ should be made certain. – H H Oct 18 '17 at 18:54
  • @HenkHolterman How is that possible? What if it's canceled because I am in the process of exiting the program, my next step is to dispose... What if I get ODE? – Snoop Oct 18 '17 at 18:55
  • When you Cancel, for whatever reason, you'll have to do `receiving.Wait()` before disposing its resources. – H H Oct 18 '17 at 18:58
  • @HenkHolterman I was thinking about that, but won't `receiving.Wait()` immediately throw an exception, completely ignoring whether the task is actually finished? – Snoop Oct 18 '17 at 18:59
  • @HenkHolterman I've ran that code, and know it does that but I guess what I am trying to ask is... Will the code actually be done executing inside of the task by the time that the `Wait` method throws its exception? – Snoop Oct 18 '17 at 19:01
  • Yes, the Wait() will block until the task completes. In your case it will re-throw the CancelException. – H H Oct 18 '17 at 19:05
  • But all in all, I would rather try to provision and keep that lib thing inside the Task. Disposing across threads isn't a great idea. – H H Oct 18 '17 at 19:07
  • @HenkHolterman I would like to, but it's constructor injected and I don't have the `ILibInterface` actually implementing `IDisposable`... thoughts? – Snoop Oct 18 '17 at 19:09
  • @HenkHolterman What if it's constructor injected without the `IDisposable` interface... as is my case? – Snoop Oct 25 '17 at 16:51

0 Answers0