如何在ASP.NET application_start中调用一些异步代码

Pur*_*ome 19 c# asp.net asynchronous async-await

在我们的application_startup中,如果不存在数据,我们会使用一些假数据为我们的数据库设定数据.

为此,我们使用这些Async方法来存储数据.大.唯一的问题是,我们不确定如何做到这一点application_startup因为那不是异步方法.

我花了太多时间试图理解@ StevenCleary的教程,而且我总是遇到死锁.我完全理解他一贯说的话:

作为一般规则,你应该使用"async all down down"; 也就是说,不要阻止异步代码

但我只是不知道我怎么能这样做,在这种情况下:(

让我们想象这是我正在尝试使用的代码......

protected void Application_Start()
{
    var someFakeData = LoadSomeFakeData();
    var documentStore = new DocumentStore();
    await documentStore.InitializeAsync(someFakeData);

    ...

    // Registers this database as a singleton.
    Container.Register(documentStore);
}
Run Code Online (Sandbox Code Playgroud)

后来......一些使用它的代码documentStore.它是通过施工注入注入的......

public SomeController(IDocumentStore documentStore)
{
    _documentStore = documentStore;
}

public ViewModel GetFoos()
{
    using (var session = _documentStore.OpenSession())
    {
        ... db code goes in here ... 
    }
}
Run Code Online (Sandbox Code Playgroud)

澄清

不是想在这里做一些异步代码.我实际上试图同步调用这个异步方法.当然,我放弃了async blah blah de blah的好处......但我很高兴.这是启动,我很高兴在启动时阻止.

Ste*_*ary 8

在这种情况下,您正在异步初始化共享资源。所以,我建议你要么保存它Task本身,要么引入一个异步包装器类型。

使用Task

protected void Application_Start()
{
  var someFakeData = LoadSomeFakeData();
  var documentStore = new DocumentStore();
  var documentStoreTask = documentStore.InitializeAsync(someFakeData);

  ...

  // Registers this database task as a singleton.
  Container.Register(documentStoreTask);
}
Run Code Online (Sandbox Code Playgroud)

不过,这可能太尴尬了,具体取决于Container. 在这种情况下,您可以引入异步包装器类型:

public sealed class DocumentStoreWrapper
{
  private readonly Task<DocumentStore> _documentStore;

  public DocumentStoreWrapper(Data data)
  {
    _documentStore = CreateDocumentStoreAsync(data);
  }

  private static async Task<DocumentStore> CreateDocumentStoreAsync(Data data)
  {
    var result = new DocumentStore();
    await documentStore.InitializeAsync(data);
    ...
    return result;
  }

  public Task<DocumentStore> DocumentStoreTask { get { return _documentStore; } }
}

protected void Application_Start()
{
  var someFakeData = LoadSomeFakeData();
  var documentStoreWrapper = new DocumentStoreWrapper(someFakeData);

  ...

  // Registers this database wrapper as a singleton.
  Container.Register(documentStoreWrapper);
}
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用AsyncLazy<T>,它做很多相同的事情,但使用后台线程来执行初始化代码。


Ami*_*neh 6

您可以使用Task.Run(() => YourAsyncMethod());内部无异步方法,例如:

    protected void Application_Start()
    {
        Task.Run(() => MyAsyncMethod(true));
    }
Run Code Online (Sandbox Code Playgroud)

  • OP 希望同步运行代码并等待其完成。这种方法通过线程池并行运行任务。不完全是他想要的东西。 (3认同)