Как исправить ошибку Cross-thread при использовании библиотеки Task Parallel? - PullRequest
0 голосов
/ 09 октября 2018
 List<Task> tasks = new List<Task>();
 tasks.Add(Task.Run(() => functionA()));
 tasks.Add(Task.Run(() => functionB()));
 tasks.Add(Task.Run(() => functionC()));



 function A(){
  List<string>lstResult =Get list ();
  control.DataSource =lstResult ;
  control.Databind();
  }



   function B(){
     List<string>lstResult =Get list ();
     control.DataSource =lstResult ;
     control.Databind();
   }



   function C(){
    List<string>lstResult =Get list ();
    control.DataSource =lstResult ;
    control.Databind();
    }

Здесь я получаю исключение Stack Empty из-за проблемы параллелизма.Как решить это.Я сталкивался с этим Stack Empty Excetpion , но нигде не упоминается, как преодолеть эту проблему.

Ответы [ 2 ]

0 голосов
/ 09 октября 2018

Нельзя изменить пользовательский интерфейс из другого потока в любой операционной системе.Этот код можно значительно упростить, если используется async/await и Task.Run перемещает внутри функций, например:

async Task functionA(){
    var results= await Task.Run(()=>Getlist1();
    control1.DataSource =results ;
    control1.Databind();
}

async Task functionB(){
    var results= await Task.Run(()=>Getlist2();
    control2.DataSource =results ;
    control2.Databind();
}

async Task functionC(){
    var results= await Task.Run(()=>Getlist3();
    control3.DataSource =results ;
    control3.Databind();
}


var tasks = await Task.WhenAll( functionA(),
                                functionB(),
                                functionC());

await ожидает завершения уже асинхронной операциибез блокировки.Когда эта операция завершается, она возвращает выполнение исходному потоку, в этом случае поток пользовательского интерфейса

0 голосов
/ 09 октября 2018

Ваш control объект может быть доступен нескольким потокам одновременно.Чтобы решить эту проблему, вы должны использовать MethodInvoker, например:

function A(){
    List<string> lstResult =Getlist();
    Invoke(new MethodInvoker(delegate
    {
        control.DataSource =lstResult ;
        control.Databind();
    }));
}
...