【发布时间】:2021-04-01 01:38:38
【问题描述】:
我有一个应用程序,它可以加载 XML 文件,然后将其解析为一些不同的类。 它有自己的窗口,带有“加载文件”之类的按钮
有一些原理图代码是什么样子的
///In main window
public void Button_Click ()
{
//(VM)DataContext.AddNewFile();
}
///In VM
public void AddNewFile()
{
//Some code with file dialogs and messages with several methods, one of which leads to AddMyType()
}
private void AddMyType(string file)
{
//Creates class of myType
}
///In Type class constructor
internal MyType(string file)
{
//Launches XML parser class to parse data from XML and create from this all MyType
data = ParseFile(file).Result;
}
///In XML parser class:
internal async Task<MyTypeData>ParseFile(file)
{
//Main method which launches background tasks and shows messages with progress bar
//Should update UI
_progress = new Progress<int>(number =>
{
_message.UpdateProgress(number);
});
someData = await Task.Run(()=> BackgroundWorkTask(rawData, _progress));
_message.Show(_maximumProgressValue); //Shows custom message with progress bar
someOtherData = await Task.Run(()=> BackgroundWorkTask(otherRawData, _progress));
}
private <T> Task BackgroundWorkTask(rawData)
{
//Some big work going here and gives some result
}
问题是 UI 冻结。
我尝试了很多变体:
Task.Wait(),等待BackgroundWorkTask并用
进行测试private <T> Task BackgroundWorkTask()
{
//Freezes
while(true){}
Task.Delay(x)
Task.Delay(x).Wait()
Thread.Sleep(x)
and await Task.Delay(x) (if private async Task)
}
我猜这是因为之前的所有主要工作都在主线程中进入同步模式。但是在启动 ParseFile() 方法之前,我确实对主线程中的数据进行了很多不同的操作。
据我了解,async 方法与 await Task.Run(()=>);用于在其他线程上做一些工作,不应阻塞 UI。
我认为使用异步方法来更新 UI 并等待不同的任务会有所帮助,但是......
如果有办法解决这个问题?
【问题讨论】:
-
你写了
ParseFile(file).Result;。它会阻止您的构造函数执行,直到您的 ParseFile 方法完成。 -
准则:总是
await方法调用返回Task,因此只能从返回Task 本身的async方法调用它们(除了可以是async void的事件处理程序) -
关于文件解析代码的构造函数,可能违反OOP原则,请查看how much work should be done in a constructor?
-
非常感谢!我会检查你所有的建议并分享结果。感谢有关构造函数的信息。
标签: c#