user2951219
user2951219

Reputation: 79

C# task.Start() doesn't run the method

I'm working on a WPF-MVVM project and I need to implement asynchronous infinite loops in some background threads. What I have done in the ViewModel is

 public TestVM()
 {
    LineIO_Task();
    //some other work
 }

and LineIO_Task is defined as

public void LineIO_Task()
{
    for (int i = 0; i < 7; i++)
    {
         Task GetP = new Task(() => { EnPost(Lines[i]); }, TaskCreationOptions.LongRunning);
         GetP.Start();

    }
}

Lines is an ObservableCollection that is initialized in TestVm. And EnPost is defined as

public async void EnPost(Line l)
{           
    int last = 0;               
    while (true)
    {
        // do the work in the loop
        int pno = l.Com.ReadPostNo();//read a serial port
        if (pno != 0 && pno != last)
        {
            log.WriteLog(pno + " to " + l.ToString());
            Dispatcher.Invoke(() =>
            {   
                // update the UI                     
                l.Posts.First(x => x.IsValid).Num = pno;
                l.Posts.First(x => x.IsValid).IsValid = false;
                LocalDb.InsertPost(l.Num, AssignedPost.ToList().Find(x => x.Num == pno));                            
            });
            pno = last;
        } 
        await Task.Delay(500);                   
    }        
}

I've tried Task.Run(() => Method()), Task.Factory.StartNew(() => Method()),,async Task EnPost() and using a System.Timers.Timer. But no matter which way I use, the EnPost method just doesn't run. I put break-points in the method. It doesn't hit there. Am I using Task wrong?

Upvotes: 1

Views: 1566

Answers (2)

user2951219
user2951219

Reputation: 79

Thanks for @Marc and @Brian's answer. They mention the"captured variable" issue, so I tried

foreach (Line l in Lines)
{ ... }

It works finally.

Upvotes: 0

Marc Gravell
Marc Gravell

Reputation: 1062780

I'm guessing this is a "captured variable" issue; try:

for (int i = 0; i < 7; i++)
{
     int index = i;
     Task GetP = new Task(() => { EnPost(Lines[index]); }, TaskCreationOptions.LongRunning);
     GetP.Start();
}

(fixed by question edit) Note however that using the thread-pool for a very long lived task is not a good idea. You might want to use a full thread instead. Also; your TaskDelay may want to be inside the while loop, in which case you can ignore the previous comment, as it is no longer actually a very long lived single piece.

Upvotes: 3

Related Questions