在分离的线程问题中初始化存储库

时间:2013-10-25 10:43:38

标签: c# multithreading winforms

在MainForm.cs中我正在初始化几件事(IBookRepository和IDocumentStore)。

private IDocumentStore _store = new EmbeddableDocumentStore {RunInMemory = false };
private IBookRepository _repository;
public MainForm()
{
    InitializeComponent();
    _store.Initialize();
    _repository = new RavenDbBookRepository(_store);
}

因为可嵌入文档存储需要一段时间(5,6秒)到init我想在单独的线程上移动它的初始化

所以我试过

 private void InitOnNewThread()
    {
        _store.Initialize();
        _repository = new RavenDbBookRepository(_Store);            
    }

public MainForm()
{
    InitializeComponent();
    Thread t = new Thread(new ThreadStart(InitOnNewThread));
    t.Start();
}

但在主线程中使用此_repository为null,因为在单独的线程中填充了原因。

因为这是我第一次尝试使用线程,所以我不知道如何克服这个问题。\

你会怎么做?

3 个答案:

答案 0 :(得分:2)

使用新的asyncawait关键字。

public class MainForm : Form
{
  private IDocumentStore _store = new EmbeddableDocumentStore {RunInMemory = false };
  private IBookRepository _repository;

  private async void MainForm_Load(object sender, EventArgs args)
  {
    // Do stuff here that does not depend on _store or _repository.
    await InitializeRepositoryAsync();
    // Now you can use _store and _repository here.
  }

  private Task InitializeRepositoryAsync()
  {
    return Task.Run(
      () =>
      {
        _store.Initialize();
        _repository = new RavenDbBookRepository(_store);
      };
  }
}

关于await如何工作的巧妙之处在于,当任务在后台异步运行时,它将抢占MainForm_Load的执行。任务完成后,MainForm_Load的剩余部分将被注入UI线程的执行流中。它的工作原理非常巧妙,可以提供非常优雅的解决方案。

答案 1 :(得分:1)

您可能想了解一下Singleton Pattern,以及在多线程环境中使用它。

由于您提到了RavenDB的DocumentStore,您可能会发现这个方便:http://ayende.com/blog/160161/managing-ravendb-document-store-startup。懒惰地初始化文档存储是一个很好的选择,而不是在app load上执行此操作。

答案 2 :(得分:-1)

您可以使用.Join()

public MainForm()
{
    InitializeComponent();
    Thread t = new Thread(new ThreadStart(InitOnNewThread));
    t.Start();
    t.Join();
}

这将等到回购准备就绪,然后再继续