簡體   English   中英

如何在ASP.NET application_start中調用一些異步代碼

[英]How to call some async code in an ASP.NET application_start

在我們的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);
}

以及稍后..使用此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的好處......但我很高興。 這是啟動,我很高興在啟動時阻止。

在這種情況下,您將異步初始化共享資源。 因此,我建議您保存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> ,它做了很多相同的事情,但使用后台線程來執行初始化代碼。

您可以使用Task.Run(() => YourAsyncMethod()); 在沒有異步方法的內部,如:

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

按照慣例,xxxAsync方法應該返回Task ,你可以從這里調用

task.RunSynchronously()

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

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(){ ....

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM