degorolls правильно, предлагая TPL, ваш код будет выглядеть следующим образом (кроме как без комментариев) (Кроме того, исключения ДОЛЖНЫ обрабатываться в TPL, так что это может сделать его не стоящим, но я не думаю, что это должно),Первые методы остались бы прежними, и да, в асинхронном программировании, основанном на событиях, заботится о безопасности потоков (т. Е. Вы всегда возвращаетесь в тот же поток, из которого вы вызывали). Я также заметил, что весь текстовый вывод выполняется вместо =из + =, но это, вероятно, больше проблема ввода в переполнение Итак, test1 и test2 будут распечатываться одновременно, однако все, что выплевывается из кода TPL, должно печататься по мере поступления. Код пользовательского интерфейса не долженделать все, что требует слишком много времени, но ... только обновление интерфейса.Итак, думаете ли вы об этом как о точке рефакторинга?Дайте мне знать, если это поможет или я пропустил то, что вы искали.
client.GetDataAsync();
client.GetDataCompleted += new EventHandler<GetDataCompletedEventArgs>(GetDataCompleted);
void GetDataCompleted(object sender, GetDataCompletedEventArgs e)
{
// Loop through the data
// ...
textBlock1.Text= "test1";
//////Dispatcher should not be needed here as this IS on the main UI thread
Dispatcher.BeginInvoke(() => textBlock1.Text= "test2" );
//////Everything that happens here should NOT be on the main UI thread, thus the cross-thread access exception
//////You can do Dispatcher.CheckAccess to determine if you need to invoke or not
//////Notice the newCopyOfDataToBeWritten. This is a closure,
//////so using the same referenced object will result in errant data as it loops
//////Also, doing it this way does not guarantee any order that this will be written out
//////This will utilize the parallel fully, but there are ways to force the order
var task = Task.Factory.StartNew(()=>
{
Dispatcher.BeginInvoke(()=>textBlock1.Text += newCopyOfDataToBeWritten)
}
);
// ...
///////I assume this is the end of the loop?
Debug.WriteLine("done");
}
.... приведенный ниже код, основанный на том, что вы опубликовали, кажется, работает для меня
var outsideThread = new Thread(()=>
{
for(int i = 0; i < 20; i++)
{
//This code will show all at once since it is on the main thread,
//which is still running
//If you want this to display one at a time also, then you need
//to use threads and callbacks like below, also
Dispatcher.BeginInvoke(()=>{textBlock1.Text += "outer" + i;});
int newI = i;
var thread = new Thread(() =>
{
System.Threading.Thread.Sleep(1000 * newI);
Dispatcher.BeginInvoke(() =>
{
//This will display as it comes in
textBlock1.Text += "inner" + newI;
});
});
thread.Start();
}
});
outsideThread.Start();