user3328870
user3328870

Reputation: 361

There is a need to define Int variable to have access from different threads?

I have function that received List of files and do work in separate threads:

private static CancellationTokenSource _tokenSource;
private static int _filesInProcess;
private static int _filesFinished;
private IEnumerable<Tuple<int, string>> _indexedSource;

public static int FilesInProcess
{
    get { return _filesInProcess; }
    set { _filesInProcess = value; }
}

public static int FilesFinished
{
    get { return _filesFinished; }
    set { _filesFinished = value; }
}

public void DoWork(int parallelThreads)
{
    _filesInProcess = 0;
    _filesFinished = 0;
    _tokenSource = new CancellationTokenSource();
    var token = _tokenSource.Token;
    Task.Factory.StartNew(() =>
    {
        try
        {
            Parallel.ForEach(_indexedSource,
                new ParallelOptions
                {
                    MaxDegreeOfParallelism = parallelThreads //limit number of parallel threads 
                },
                file =>
                {
                    if (token.IsCancellationRequested)
                        return;
                    //do work...
                });
        }
        catch (Exception)
        { }

    }, _tokenSource.Token).ContinueWith(
            t =>
            {
                //finish...
            }
        , TaskScheduler.FromCurrentSynchronizationContext() //to ContinueWith (update UI) from UI thread
        );
}

As you can see i have 2 variables that indicate how many files already start and how many finished (_filesInProcess and _filesFinished)

My questions:

  1. Do I need to set these variables to be accessed from different threads or this is OK ?
  2. After the function finished and all my files finished to play and i want to start a new one, there is option to do from Task class or simple while will do the work for me ?

Upvotes: 2

Views: 70

Answers (1)

oleksii
oleksii

Reputation: 35905

1 Do I need to set these variables to be accessed from different threads or this is OK ?

Yes you do. Couple of things. You should add a volatile keyword to the declarations of the counters, like

private static volatile int _filesInProcess;

This ensures that all the reads actually read the current value, in contrast to reads of a cashed value. If you want to modify and read the counters, you should consider using the Interlocked class, for example Interlocker.Increment

2 After the function finished and all my files finished to play and i want to start a new one, there is option to do from Task class or simple while will do the work for me ?

Not sure about this one, wild guess (it's not clear what you need). You can use task continuations, like you did (last block of code). As alternative a Task.Factory.StartNew returns a task, which you could save to a local variable and start it as you please (say on a button click). You may need to update the code slightly as Task.Factory.StartNew will kick the task immediately, while you may only want to create a task and run it on an event.

Based you your comment you can do something like (coded in notepad)

private Task _task; // have a local task variable

// move your work here, effectively what you have in Task.Factory.StartNew(...)
public void SetupWork()
{
    task = new Task (/*your work here*/);
    // see, I don't start this task here
    // ...
}

// Call this when you need to start/restart work
public void RunWork()
{
    task.Run();
}

Upvotes: 2

Related Questions