簡體   English   中英

NET Core BackgroundService:“任務已取消。” 錯誤

[英]NET Core BackgroundService: "A task was canceled." Error

您好,我開發了 BackgroundService,它用於監視 Oracle 數據庫,當新記錄插入源表時,將記錄復制到 SQL 服務器數據庫中。 但過了一段時間(有時 1 天,有時 2 天)。 我的服務已停止工作。 錯誤提示:“任務已取消”。 我不明白為什么我的代碼突然停止工作。

注意:我的應用程序托管在 IIS (Windows Server 2012)

  • 我想無休止地運行我的應用程序。

這是我的代碼:

public class MainTransactionService : BackgroundService
    {   
    private readonly ILogger Logger;
    private readonly TransactionSettings TSettings;
    public MainTransactionService(ILogger logger, TransactionSettings tSettings)
    {
        TSettings = tSettings;
        Logger = logger;
    }
    protected async override Task ExecuteAsync(CancellationToken stoppingToken)
    {
        //Create a connection to Oracle         
        string conString = "";

        //How to connect to an Oracle DB without SQL*Net configuration file
        //  also known as tnsnames.ora.
        //"Data Source=orclpdb";
        "Data Source=eoffice";

        OracleConfiguration.OracleDataSources.Add("eoffice", "");

        //How to connect to an Oracle DB with a DB alias.
        //Uncomment below and comment above.
        //"Data Source=<service name alias>;";

        OracleConnection con = new OracleConnection(conString);
        Logger.Information("Connected to Oracle");
        OracleCommand cmd = con.CreateCommand();

        try
        {
            Logger.Information("Run part executed");

            if (con.State != ConnectionState.Open)
            {
                con.Open();
            }
            
            while (!stoppingToken.IsCancellationRequested)
            {
                await Task.Delay(TSettings.Frequency, stoppingToken);
                //Logger.Information(stoppingToken.IsCancellationRequested.ToString());

                try
                {
                    var cancelTask = Task.Delay(TSettings.Timeout, stoppingToken);

                    //Logger.Information("CODE EXECUTED");
                    //await context.Response.WriteAsync("Server is Listening");

                    //OracleConfiguration.OracleDataSources.Add("orclpdb", "(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = miatdw1.miat.com.mn)(PORT = 1521)))(CONNECT_DATA = (SERVICE_NAME = orclpdb.miat.com.mn)))");

                    //Check Oracle
                    Logger.Information("Establishing Oracle Connection (While)");
                    cmd.CommandText = "select MAX(id) from PB_TRANSACTION";
                    int SourceTableMaxId = Convert.ToInt32(cmd.ExecuteScalar());

                    //Check SQL
                    SqlConnection conn = new SqlConnection("");
                    SqlCommand check_id = new SqlCommand("select MAX(id) from PB_TRANSACTION", conn);
                    Logger.Information("Establishing MS-SQL Connection");
                    conn.Open();
                    int TargetTableMaxId = Convert.ToInt32(check_id.ExecuteScalar());

                    if (SourceTableMaxId > TargetTableMaxId)
                    {
                        int TotalNewRecords = SourceTableMaxId - TargetTableMaxId;

                        Logger.Information(TotalNewRecords.ToString() + " New Records Found");


                        OracleCommand command = new OracleCommand();
                        command.CommandText = "select * from (select * from pb_transaction order by id desc) x where ROWNUM <= :lastrecord";
                        command.Parameters.Add(":username", OracleDbType.Int32).Value = TotalNewRecords;
                        command.Connection = con;

                        Logger.Information("Retrieved " + TotalNewRecords.ToString() + " from PB_TRANSACTION table.");

                        Transaction LastTransaction = new Transaction();

                        using (OracleDataReader oReader = command.ExecuteReader())
                        {
                            while (oReader.Read())
                            {
                                LastTransaction.Id = Convert.ToInt32(oReader["ID"]);
                                LastTransaction.type = oReader["TYPE"].ToString();
                                LastTransaction.account = oReader["ACCOUNT"].ToString();
                                LastTransaction.journal_id = oReader["JOURNAL_ID"].ToString();
                                LastTransaction.amount = Convert.ToDouble(oReader["AMOUNT"]);
                                LastTransaction.currency = oReader["CURRENCY"].ToString();
                                LastTransaction.posted_date = oReader["POSTED_DATE"].ToString();
                                LastTransaction.statement_date = oReader["STATEMENT_DATE"].ToString();
                                LastTransaction.description = oReader["DESCRIPTION"].ToString();
                                LastTransaction.pnr = oReader["PNR"].ToString();
                                LastTransaction.pnr_approved = Convert.ToInt32(oReader["PNR_APPROVED"]);
                                LastTransaction.jid = oReader["JID"].ToString();
                                LastTransaction.user_id = oReader["USER_ID"].ToString();
                                LastTransaction.inserted_date = oReader["INSERTED_DATE"].ToString();

                                SqlCommand scmd = new SqlCommand("insert into PB_TRANSACTION (ID,TYPE, ACCOUNT, JOURNAL_ID, AMOUNT, CURRENCY, POSTED_DATE, STATEMENT_DATE, DESCRIPTION, PNR, PNR_APPROVED, JID, USER_ID, INSERTED_DATE) values(@id,@type,@account,@journalid, @amount,@currency,@posteddate,@statementdate,@description,@pnr,@pnrapproved,@jid,@userid,@inserteddate);", conn);
                                scmd.Parameters.AddWithValue("@id", LastTransaction.Id);
                                scmd.Parameters.AddWithValue("@type", LastTransaction.type);
                                scmd.Parameters.AddWithValue("@account", LastTransaction.account);
                                scmd.Parameters.AddWithValue("@journalid", LastTransaction.journal_id);
                                scmd.Parameters.AddWithValue("@amount", LastTransaction.amount);
                                scmd.Parameters.AddWithValue("@currency", LastTransaction.currency);
                                scmd.Parameters.AddWithValue("@posteddate", LastTransaction.posted_date);
                                scmd.Parameters.AddWithValue("@statementdate", LastTransaction.statement_date);
                                scmd.Parameters.AddWithValue("@description", LastTransaction.description);
                                scmd.Parameters.AddWithValue("@pnr", LastTransaction.pnr);
                                scmd.Parameters.AddWithValue("@pnrapproved", LastTransaction.pnr_approved);
                                scmd.Parameters.AddWithValue("@jid", LastTransaction.jid);
                                scmd.Parameters.AddWithValue("@userid", LastTransaction.user_id);
                                scmd.Parameters.AddWithValue("@inserteddate", LastTransaction.inserted_date);
                                scmd.ExecuteNonQuery();
                            }
                            Logger.Information(TotalNewRecords.ToString() + " records inserted");
                        }
                    }
                    else
                    {
                        Logger.Information("No New Records found");
                    }
                }
                catch (Exception ex)
                {
                    LogError("INNER TRY: " + ex.Message);
                }
            }
            Logger.Information("Oracle Database connection has successfully Disconnected!!!");
        }
        catch (TaskCanceledException tex)
        {
            LogError("TASK ERROR: " + tex.Message);
        }
        catch (Exception ex)
        {
            LogError("MAIN ERROR: " + ex.Message);
        }
        finally
        {
            con.Close();
            con.Dispose();
        }
    }

    public async override Task StopAsync(CancellationToken cancellationToken)
    {
        await base.StopAsync(cancellationToken);
    }
    private void LogError(string error)
    {
        Logger.Error(error);
    }
} 

我的應用程序托管在 IIS (Windows Server 2012)

我想無休止地運行我的應用程序。

只要您的 ASP.NET 應用程序運行,在 ASP.NET 中托管在 IIS 中的BackgroundService就會運行。 就是這樣。 由於 ASP.NET/IIS 將定期重新啟動,因此您的BackgroundService將定期關閉(並重新啟動)。 ASP.NET 和 IIS 都不是為長期存在的后台進程設計的; 它們專為 HTTP 服務而設計。 在一般情況下(即雲提供商),您的應用實際上可能會關閉,直到下一個 HTTP 請求到來。

如果這是不可接受的,則 ASP.NET/IIS 不是滿足您需要的正確主機。 您可以使用 Win32 服務主機而不是 ASP.NET/IIS,方法是使用 Worker Service 模板創建一個新項目,添加 Win32 服務生命周期,並在該應用程序中而不是在您的 ASP.NET 應用程序中托管相同的BackgroundService

暫無
暫無

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

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