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

时间:2015-02-26 06:13:34

标签: c# asp.net asynchronous async-await

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

为此,我们使用Async方法存储数据。大。唯一的问题是,我们不确定如何在application_startup中执行此操作,因为这不是异步方法。

我花了很多时间试图理解@ StevenCleary的教程,而且我总是陷入僵局。我完全grok what he consistently says

  

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

但我不知道如何做到这一点,在这种情况下:(

让我们想象这就是我试图玩的代码......

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

    ...

    // Registers this database as a singleton.
    Container.Register(documentStore);
}

以及稍后..使用此documentStore的一些代码。它是通过施工注入注入的......

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

public ViewModel GetFoos()
{
    using (var session = _documentStore.OpenSession())
    {
        ... db code goes in here ... 
    }
}

澄清

尝试在此处执行某些异步代码。我实际上试图调用此异步方法,同步。当然,我放弃了async blah blah de blah的好处......但我很高兴。这是启动,我很高兴在启动时阻止。

4 个答案:

答案 0 :(得分:4)

在这种情况下,您可以异步初始化共享资源。因此,我建议您保存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);
}

这可能太尴尬了,取决于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);
}

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

答案 1 :(得分:1)

你可以使用Task.Run(() => YourAsyncMethod());内部的无同步方法,如:

    protected void Application_Start()
    {
        Task.Run(() => MyAsyncMethod(true));
    }

答案 2 :(得分:-2)

按照惯例,xxxAsync方法应该返回Task,从这里你可以调用

task.RunSynchronously()

https://msdn.microsoft.com/en-us/library/dd321435%28v=vs.110%29.aspx

答案 3 :(得分:-2)

public static class AsyncHelper
{
    private static readonly TaskFactory MyTaskFactory = new
    TaskFactory(CancellationToken.None,
                TaskCreationOptions.None,
                TaskContinuationOptions.None,
                TaskScheduler.Default);

    public static TResult RunSync<TResult>(Func<Task<TResult>> func)
    {
        return MyTaskFactory
          .StartNew(func)
          .Unwrap()
          .GetAwaiter()
          .GetResult();
    }
    public static void RunSync(Func<Task> func)
    {
        MyTaskFactory
          .StartNew(func)
          .Unwrap()
          .GetAwaiter()
          .GetResult();
    }
}

然后用作

AsyncHelper.RunSync(ProcessAsync);

private async Task ProcessAsync(){ ....