取消多线程任务,包括运行.dll

时间:2019-07-24 06:41:53

标签: c# excel asynchronous com task

我有2个不同的任务,它们是同步启动的。其中之一是我调用.dll来创建COM对象(写入Excel文件)的方法。当我终止两个任务时,Excel文件仍在使用中,因此无法删除它。这就是我称这两个任务的方式:

private CancellationTokenSource cancel_1 = new CancellationTokenSource();
private CancellationTokenSource cancel_2 = new CancellationTokenSource();

    private void Form1_Load(object sender, System.EventArgs e)
    {
        cancel_1 = new CancellationTokenSource();
        var task_1 = Task.Factory.StartNew(() => DoWork1(), cancel_1.Token);

        //2nd task
        cancel_2 = new CancellationTokenSource();
        var task_2 = Task.Factory.StartNew(() => DoExcelWork(), cancel_2.Token);
    }

然后我尝试取消form_closing中的两个任务:

private void Form1_FormClosing(object sender, System.Windows.Forms.FormClosingEventArgs e)
{
   //Cancel all running processes
   cancel_1.Cancel();
   cancel_2.Cancel();

   // I've also set a variable for check if Task_2 is running and try to clear COM 
   // object with clearing GC(), but It's not working
   if (excel_running)
   {
       GC.Collect();
       GC.WaitForPendingFinalizers();
       GC.Collect();
       GC.WaitForPendingFinalizers();

       string filename = Environment.GetFolderPath(Environment.SpecialFolder.Desktop).ToString() + @"\" + "sample.xlsx";
       File.Delete(filename)

   }
}

但是,这不是终止.dll为写入Excel文件而启动的过程。我注意到在后台运行进程是“ COM代理”,因此,如您所见,我尝试在2个周期内清理GC(),但文件仍在使用中。

我在线程中的方法代码如下:

public void DoExcelWork()
{
    try
    {
        using (var con = new OracleConnection(conn_string))
        {
            con.Open();

            using (OracleCommand cmd = new OracleCommand("myprocedure"))
            {
                cmd.Connection = con;
                cmd.CommandType = CommandType.StoredProcedure;

                cmd.Parameters.Add(new OracleParameter("par1", OracleDbType.NVarchar2) { Direction = ParameterDirection.Input, Value = SQL_string });

                cmd.Parameters.Add(new OracleParameter("result", OracleDbType.RefCursor)).Direction = ParameterDirection.Output;

                //Here is the call of .dll             
                Export export_xml = new Export();
                export_xml.Save_to_Excel(cmd);

                excel_running = false;

                if (cancel_2.IsCancellationRequested)
                {
                   cmd.Cancel();
                   return;
                }

    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message + "in " + ex.StackTrace);
    }
}

我的问题是-如何正确取消后台进程,以便即使运行.dll也将关闭?

1 个答案:

答案 0 :(得分:0)

已解决。我必须重新组织DoExcelWork()方法以接受CancellationToken的其他参数,然后在方法中调用“ token.IsCancellationRequested”关闭所有正在创建Excel文件的对象。