我正在做翻译。 UI是WPF应用程序。单击按钮,我启动一个必须写入ui的长任务。过去,我和背景工作者做过类似的事情。我意识到后台工作者已经过时了,异步是要走的路(更少噪音和更清洁等)。
我有一项漫长的任务,即在循环时顺利地将文字写入屏幕,但屏幕仍然“冻结”,即无法点击按钮等。
如果我在task.run结束时添加30毫秒的睡眠,则ui会响应并且我的对象事件正在运行。但睡眠似乎比30毫秒慢得多。
private void AnalyzeButton_Click( object sender, RoutedEventArgs e )
{
var flowManager = new InterpreterFlowManager(){ ... }
flowManager.Initialize();
flowManager.ContinueFlow();
}
....
public class InterpreterFlowManager
{
async public void ContinueFlow()
{
string LineBuffer = "";
string lastTextBlockString = "";
while (...)
{
lastTextBlockString = "";
bool endLoop = false;
await Task.Run(() =>
{
if (...)
{
...
if (...)
{
switch (...)
{
case x:
lastTextBlockString = "\r\nEntrer un nombre :";
endLoop = true;
break;
case y:
lastTextBlockString = "\r\n" + ConsoleInfo.Message;
break;
}
}
}
else
LineIndex++;
*********************************
SMALL SLEEP HERE MAKE UI RESPONSIVE.
************************************
});
//ACCESS TO A UI TEXTBOX
var lastTextBlock = (InteractiveWindow.Children.Cast<TextBox>().Where(c => c.GetType() == typeof(TextBox) && c.IsReadOnly)).Last();
//SUCESSFULLY APPEND
lastTextBlock.Text += lastTextBlockString;
Output.Text += _tmpResultString + "\r\n";
_tmpResultString.Clear();
if (endLoop)
{
TextBox input = new TextBox();
input.BorderBrush = Brushes.DarkRed;
input.KeyUp += input_KeyUp; // further stuff
InteractiveWindow.Children.Add(input);
return;
}
}
}
}
答案 0 :(得分:3)
如果您熟悉BackgroundWorker
,那么async
世界就会有一个非常直接的翻译:
BackgroundWorker
电话替换每个Task.Run
个实例。ProgressChanged
事件处理程序替换为Progress<T>
(described on MSDN)。RunWorkerCompleted
事件替换为await Task.Run(...)
。您的代码看起来像是在Task.Run
循环中开始单独的while
。如果每个Task.Run
中的代码执行得非常快,那么这将不会让您的UI有机会做出响应。考虑移动while
代理中的Task.Run
循环并使用IProgress<T>
/ Progress<T>
进行更新。