2017-10-02 5 views
0

これはシンプルデイリートリガークラスで、私はこの関数を - >( "DailyTrigger(int hour、int minute、int second = 0)")と呼んでいます。 それが次回働い初めて(Task.delayを使用して)エラー非同期メソッドエラーhelp me

public class DailyTrigger 
{ 
    readonly TimeSpan triggerHour; 

    public DailyTrigger(int hour, int minute , int second = 0) 
    { 
     triggerHour = new TimeSpan(hour, minute, second); 
     InitiateAsync(); 
    } 

    async void InitiateAsync() 
    { 
     while (true) 
     { 
      var triggerTime = DateTime.Today + triggerHour - DateTime.Now; 
      if (triggerTime < TimeSpan.Zero) 
       triggerTime = triggerTime.Add(new TimeSpan(0,2,0)); 
      await Task.Delay(triggerTime); 
      OnTimeTriggered?.Invoke(); 

     } 
    } 

コントローラ中からコール

var trigger = new DailyTrigger(13,01); 
       trigger.OnTimeTriggered +=() => 
       { 
        var res = AanModel.GetById<Company_Priority>(prio_obj.id); 
        res.version = "5"; 
        res.Create(); 
       }; 

というエラー

"An asynchronous module or handler completed while an asynchronous operation was still pending"

+0

ここでは何を達成しようとしていますか?何らかの種類のスケジュールされたタスクを実装している場合は、このようにすることはできません。 – Euphoric

+1

これは[tag:asp.net]コンテキストにある場合、[ASP.NETでバックグラウンドタスクを実行する方法](https://www.hanselman.com/blog/HowToRunBackgroundTasksInASPNET.aspx) –

答えて

3

これはあります非同期プログラミングのよく知られた問題です。どのように動作するかを理解するには、Quick tip: Avoid ‘async void’のような記事をjonpreeceで読むことをお勧めします。

エラー:

An asynchronous module or handler completed while an asynchronous operation was still pending.

説明:

Yep, you have a race condition. The method returned before it finished executing. Under the hood, the framework didn’t create a Task for the method because the method does not return a Task. Therefore when calling FirstOrDefaultAsync, the method does not pause execution and the error is encountered.

ソリューション:

To resolve the problem, simply change the return type of the method from void to Task. Don’t worry, you don’t actually have to return anything, and the compiler knows not to generate a build error if there is no return statement. An easy fix, when you know what the problem is!

UPDATE:

もしあなたのコンストラクタ内の非同期メソッドを呼び出すにはまだしたいプッシュあなたはAsync OOP 2: ConstructorsによってスティーブンClearyによってよく読む。

Asynchronous construction poses an interesting problem. It would be useful to be able to use await in a constructor, but this would mean that the constructor would have to return a Task representing a value that will be constructed in the future, instead of a constructed value. This kind of concept would be very difficult to work into the existing language.

The bottom line is that async constructors are not allowed, so let’s explore some alternatives.

そして、あなたは、あなたがそれをチェックアウトより良い

public sealed class MyClass 
{ 
    private MyData asyncData; 
    public MyClass() 
    { 
    InitializeAsync(); 
    } 

    // BAD CODE!! 
    private async void InitializeAsync() 
    { 
    asyncData = await GetDataAsync(); 
    } 
} 

をしない何..

を見ることができます十分に読めば、それは非常に興味深い読み取ります。

+0

に感謝します。あなたの反応。しかし私はパブリックDailyTrigger(int、int、int)からiInitiateAsync()を呼び出すため、Taskにvoidを変更できません。私はInitiateAsync()を待つ必要があります。その呼び出しが待たれていないからです。 –