To begin, structure your program. The part that deals with the presentation (View) must be separated from the control part (ViewModel), and from various engines (Model).
When the ViewModel decides to open the file, the request to open and parse the content should go to the file parsing engine and build the object model. The model itself may well be single-threaded, but let business logic be engaged in transferring information between threads.
So, at the model level, your code is simple and linear:
public Document ReadFromFilename(string filename) { using (var fs = new FileStream(filename, FileMode.Open)) return ReadFromStream(fs); } protected Document ReadFromStream(IStream stream) { ...
At the VM level, you need a little more:
public void async OpenDocumentAsync(string filename) { try { // установить статус ожидания this.ReadStatus = ReadStatus.Reading; // распарсить документ var doc = await DocumentHelper.GetDocumentAsync(filename); // создать VM-структуру var vmDoc = new VM.Document(doc); // установить текущую страницу и создать соответствующие подструктуры await vmDoc.SwitchToPageAsync(0); // доложить, что всё в порядке this.ReadStatus = ReadStatus.Ready; // не забыть обновить свойство DataContext'а this.Document = vmDoc; } catch (<что нужно>) { // доложить, что что-то пошло не так this.ReadStatus = ReadStatus.Failed; } }
The DocumentHelper.GetDocumentAsync
method will look something like this:
public Task<Model.Document> GetDocumentAsync(string filename) { var t = new Task(() => model.ReadFromFilename(filename)); t.Start(taskSchedulers[model]); return t; }