【发布时间】:2018-06-03 11:23:02
【问题描述】:
我正在尝试将大型文本文件读入文本框,并在将文件拖到文本框时保持 ui 响应。
无法按预期工作,Windows 窗体被冻结,似乎只能执行读取文件并将内容附加到文本框的任务。
IDE 抛出了 ContextSwitchDeadLock,但并不是真正的错误。 这是一项长期运行的任务。我已修复它更改异常菜单下的行为。
感谢 JSteward,Peter 将代码更改为此。
运行此任务时如何保持 ui(主线程)响应? 谢谢。
private SynchronizationContext fcontext;
public Form1()
{
InitializeComponent();
values.DragDrop += values_DragDrop; //<----------- This is a textbox
fcontext = WindowsFormsSynchronizationContext.Current;
}
// The async callback
async void values_DragDrop(object sender, DragEventArgs e)
{
try
{
string dropped = ( (string[]) e.Data.GetData(DataFormats.FileDrop))[0];
if ( dropped.Contains(".csv") || dropped.Contains(".txt"))
{
using ( StreamReader sr = File.OpenText(dropped) )
{
string s = String.Empty;
while ( ( s = await sr.ReadLineAsync() ) != null )
{
values.AppendText(s.Replace(";",""));
}
}
}
}
catch (Exception ex) { }
}
【问题讨论】:
-
您可以只使用
...AppendText(await ...ReadLineAsync)而不是使用Fileapi 的阻塞变体。这样您就不需要手动存储或发布到上下文。 -
我认为你的意思是它只能应用于
asynclamda 表达式。你能更新问题中的代码吗? -
您将无法从
Task.Run默认上下文中AppendText。使用asyncapi,您不应该需要Task.Run,但要了解您的拖放可能会在您完成读取文件之前结束。此外,您可能需要分批加载文件以保持 ui 响应并让Forms循环轮到它。 -
“问题似乎是加载函数” -- 你认为什么函数是“加载函数”? @JSteward 已经解释说您不需要
Task.Run(),因为您正在使用 async/await 进行阅读。实际回答您的问题是不可能的,因为您没有提供一个很好的minimal reproducible example 来重现该问题。但是,很可能您一次读取的数据太少,更新请求使 UI 线程饱和,这与阻止它一样糟糕。尝试重构代码,使 UI 更新仅每 100-500 毫秒左右发生一次。 -
“我认为问题是完整且可验证的” -- 如果您是回答问题的人,那么您认为可能是相关的。但是,你不是,它不是。请阅读minimal reproducible example。另外,请阅读How to Ask,以及该页面底部链接的所有文章,以便您了解minimal reproducible example 的实际含义,以及以清晰、可回答的方式提出您的问题所需的内容。
标签: c# winforms async-await task-parallel-library