从ActionResults调用Async方法

时间:2016-08-24 18:20:11

标签: c# asp.net-mvc

我有一个ActionResult方法上传文件并调用CSVReader();方法读取文件并将其写入数据库。但是,当代码运行时,我得到关于ActionResult方法不是异步的错误。这是我的代码:(有很多)

public class files
{
    public ObjectId _id { get; set; }
    public string product_name { get; set; }
    public string part_number { get; set; }
    public string quantity { get; set; }
    public string customer { get; set; }
    public string reference { get; set; }
    public string contact { get; set; }
    public string quote_number { get; set; }
    public string customer_po { get; set; }
    public string order_date { get; set; }
    //public string count { get; set; }
}


public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }


   [HttpPost]
    public ActionResult Index(HttpPostedFileBase file)

    {
        if (file != null && file.ContentLength > 0)
        {
            var fileName = System.IO.Path.GetFileName(file.FileName);
            var path = System.IO.Path.Combine(("C:\\Dev\\ProductionOrderWebApp\\Uploads"), fileName);
            file.SaveAs(path);
            CSVReader(fileName);
        }
        return RedirectToAction("Index");
    }

    public static async void CSVReader(string fileName)
    {

        StreamReader oStreamReader = new StreamReader(fileName);

        DataTable oDataTable = null;
        int RowCount = 0;
        string[] ColumnNames = null;
        string[] oStreamDataValues = null;
        //using while loop read the stream data till end
        while (!oStreamReader.EndOfStream)
        {
            String oStreamRowData = oStreamReader.ReadLine().Trim();
            if (oStreamRowData.Length > 0)
            {
                oStreamDataValues = oStreamRowData.Split(',');
                //Bcoz the first row contains column names, we will poluate 
                //the column name by
                //reading the first row and RowCount-0 will be true only once
                if (RowCount == 0)
                {
                    RowCount = 1;
                    ColumnNames = oStreamRowData.Split(',');
                    oDataTable = new DataTable();

                    //using foreach looping through all the column names
                    foreach (string csvcolumn in ColumnNames)
                    {
                        DataColumn oDataColumn = new DataColumn(csvcolumn.ToUpper(), typeof(string));

                        //setting the default value of empty.string to newly created column
                        oDataColumn.DefaultValue = string.Empty;

                        //adding the newly created column to the table
                        oDataTable.Columns.Add(oDataColumn);
                    }
                }
                else
                {
                    //creates a new DataRow with the same schema as of the oDataTable            
                    DataRow oDataRow = oDataTable.NewRow();

                    //using foreach looping through all the column names
                    for (int i = 0; i < ColumnNames.Length; i++)
                    {
                        oDataRow[ColumnNames[i]] = oStreamDataValues[i] == null ? string.Empty : oStreamDataValues[i].ToString();
                    }

                    //adding the newly created row with data to the oDataTable       
                    oDataTable.Rows.Add(oDataRow);
                }
            }
        }
        //close the oStreamReader object
        oStreamReader.Close();
        //release all the resources used by the oStreamReader object
        oStreamReader.Dispose();

        //Looping through all the rows in the Datatable
        foreach (System.Data.DataRow oDataRow in oDataTable.Rows)

        {
            Upload vtx = new Upload();
            files csv = new files();
            csv.product_name = oDataRow[0].ToString();
            csv.part_number = oDataRow[1].ToString();
            csv.quantity = oDataRow[2].ToString();
            csv.customer = oDataRow[3].ToString();
            csv.reference = oDataRow[4].ToString();
            csv.contact = oDataRow[5].ToString();
            csv.quote_number = oDataRow[6].ToString();
            csv.customer_po = oDataRow[7].ToString();
            csv.order_date = oDataRow[8].ToString();
            //csv.count = Convert.ToString(count);

            await vtx.VIGL.InsertOneAsync(csv);
            //count++;

            string RowValues = string.Empty;

            //Looping through all the columns in a row
            //var count = 1;
            foreach (string csvcolumn in ColumnNames)

            {

            }
        }
    }

    public class Upload //Constructor
    {
        public IMongoDatabase db;
        internal Upload()
        {

            MongoClient client = new MongoClient();//insert connection string in brackets
            this.db = client.GetDatabase("POWA");
            var collection = db.GetCollection<files>("Imported");
        }

        internal IMongoCollection<files> VIGL          // Good idea to expose all collections as properties
        {
            get
            {


                return db.GetCollection<files>("Imported");
            }
        }

    }



    public ActionResult FileDisplay()
    {
        return View();
    }


}

我已经让它在MVC(控制台)之外工作,但是ActionResult会抛出异步错误。如何在不抛出错误的情况下调用CSVReader();方法?

1 个答案:

答案 0 :(得分:4)

最好使用async / await down整个调用堆栈,这可能是MVC所能实现的。将您的操作标记为异步,然后使用await关键字等待CsvReader方法的结果。

// changed signature to async and Task<ActionResult>
[HttpPost]
public async Task<ActionResult> Index(HttpPostedFileBase file)
{
    if (file != null && file.ContentLength > 0)
    {
        var fileName = System.IO.Path.GetFileName(file.FileName);
        var path = System.IO.Path.Combine(("C:\\Dev\\ProductionOrderWebApp\\Uploads"), fileName);
        file.SaveAs(path);
        // add await
        await CSVReader(fileName);
    }
    return RedirectToAction("Index");
}

// did not check the code in the method but the signature should return type Task
public static async Task CSVReader(string fileName) {/*existing/unchanged code*/}

旁注

对你来说,最好的办法是对async / await模式进行一些阅读,这样你就不会只是复制/粘贴而不了解实际发生的事情以及你使用它的原因。它还可以帮助您稍后对可能出现的问题进行故障排除/调试。