none
想請教async非同步的概念 RRS feed

  • 問題

  • 網頁使用ajax呼叫 ColumnListAsync,當執行到await的時候,程式就自動拆成兩塊,
    一塊是執行  ColumnAsync,另一快則是繼續往下跑。
    問題一:ColumnAsync這邊如果不用async的話,會導致return charData 出現錯誤,無法將 Generic.List<object>' 隱含轉換成 'Tasks.Task<System.Collections.Generic.List<object>>',但加了asyn又會出現 警示 說沒有使用await。但因ColumnAsync內 需按照順序執行,
    不然無法取得dtCol。
    問題二(已解):承上題,曾經試過把從資料庫取得的值改寫成async的方法,但到了await就直接跳出,繼續執行下面的程式,
    使用Task.wait也沒有等到他將裡面的值丟出,導致dtCol抓不到值。把dt.wait();移到 dtCol = await dt;下面就有值了,應該是當執行到 await時 會先往下執行,故需使用wait()才會有動作。
    問題三:
    Task<DataTable> dt = dbHelp.DatatableAsync(sqlColumnPar,SqlConnString());            
    datatable dtCol =await dt;
    可以簡寫成 
    datatable dtCol = await dbHelp..DatatableAsync(sqlColumnPar,SqlConnString());
    那如果要使用wait 要怎麼寫?

    以上觀念或程式如果有錯誤還麻煩糾正,感謝您將文章看完。

    [HttpGet]	    
            public async Task<List<object>> ColumnListAsync(string colName, int NowPage, string process)
            {
                List<object> charData = await ColumnAsync(colName, NowPage, process);
                return charData;
            }
            public async Task<List<object>> ColumnAsync(string colName, int NowPage, string process)
            {
                int pageRows = 12;
                int page = NowPage;
                List<Object> charData = new List<object>();
                dbHelpClass dbHelp = new dbHelpClass();
                DataTable dtCol = new DataTable();
    
                //取得欄位名稱
                string sqlColumnPar = @"SELECT [CHN_name],[AxObjNo],[USL],[SL],[LSL],[RelaTBclms]      
                      FROM [cbccuredb].[dbo].[K_P_CuringMrg_para]
                      where processName = 'Curing' and isUsing = 1
                      order by AxObjNo";
                //Task<DataTable> dt = dbHelp.DatatableAsync(sqlColumnPar,SqlConnString());
                //dt.Wait();
                //dtCol =await dt;
                dtCol = dbHelp.GetDataTable(sqlColumnPar, SqlConnString());
     
    
                //根據頁數取得欄位
                var colEnu = from p in dtCol.AsEnumerable()
                             select p;
                var colPar = colEnu.Skip((page - 1) * pageRows).Take(pageRows).ToList();
    
                foreach (DataRow dRow in colPar)
                {
                    List<object> objRow = new List<object>();
    
                    charData.Add(new object[] { dRow["CHN_name"], dRow["USL"], dRow["SL"], dRow["LSL"],dRow["RelaTBclms"] });
                }
                return charData;
            }
    		 public async Task<DataTable> DatatableAsync(string strSql, string sqlConn)
    		{
    			try
    			{
    				using (SqlConnection conn = new SqlConnection(sqlConn))
    				{
    					DataTable dt = new DataTable();
    					//if (conn.State == ConnectionState.Closed)
    						await conn.OpenAsync();
    					using (SqlCommand command = new SqlCommand(strSql, conn))
    					{
    						using (SqlDataReader dr = await command.ExecuteReaderAsync())
    						{
    							if (await dr.ReadAsync())
    							{
    								dt.Load(dr);
    								return dt;
    							}
    							else
    							{
    								return null;
    							}
    						}
    					}
    				}
    			}
    			catch(Exception ex)
    			{
    				throw ex;
    			}
    			
    		}

    2015年12月18日 上午 07:15

解答

  • 問題一:ColumnAsync這邊如果不用async的話,會導致return charData 出現錯誤,無法將 Generic.List<object>' 隱含轉換成 'Tasks.Task<System.Collections.Generic.List<object>>',但加了asyn又會出現 警示 說沒有使用await。但因ColumnAsync內 需按照順序執行,
    不然無法取得dtCol。

    不用 async 的話,回傳型別要改成 List<object>,只是 List<object> 這用法也很怪,沒有強型別的好處,最好連這個也改一改,例如使用 ViewModel。

    問題三:
    Task<DataTable> dt = dbHelp.DatatableAsync(sqlColumnPar,SqlConnString());            
    datatable dtCol =await dt;
    可以簡寫成 
    datatable dtCol = await dbHelp.DatatableAsync(sqlColumnPar,SqlConnString());
    那如果要使用wait 要怎麼寫?

    為什麼要用 wait... 這樣寫不就好了?


    強力監督SQL Injection問題!!

      • 小朱的技術隨手寫:http://www.dotblogs.com.tw/regionbbs/
      • 雲端學堂Facebook: http://www.facebook.com/studyazure

    • 已標示為解答 Daimom 2015年12月21日 上午 04:01
    2015年12月20日 上午 03:43
    版主

所有回覆

  • 問題一:ColumnAsync這邊如果不用async的話,會導致return charData 出現錯誤,無法將 Generic.List<object>' 隱含轉換成 'Tasks.Task<System.Collections.Generic.List<object>>',但加了asyn又會出現 警示 說沒有使用await。但因ColumnAsync內 需按照順序執行,
    不然無法取得dtCol。

    不用 async 的話,回傳型別要改成 List<object>,只是 List<object> 這用法也很怪,沒有強型別的好處,最好連這個也改一改,例如使用 ViewModel。

    問題三:
    Task<DataTable> dt = dbHelp.DatatableAsync(sqlColumnPar,SqlConnString());            
    datatable dtCol =await dt;
    可以簡寫成 
    datatable dtCol = await dbHelp.DatatableAsync(sqlColumnPar,SqlConnString());
    那如果要使用wait 要怎麼寫?

    為什麼要用 wait... 這樣寫不就好了?


    強力監督SQL Injection問題!!

      • 小朱的技術隨手寫:http://www.dotblogs.com.tw/regionbbs/
      • 雲端學堂Facebook: http://www.facebook.com/studyazure

    • 已標示為解答 Daimom 2015年12月21日 上午 04:01
    2015年12月20日 上午 03:43
    版主
  • 小朱大 您好,

          第一個問題,因為是使用web api傳jason回去,所以才用List<object>,這樣的寫法會很怪嗎?

    第三個問題要用wait的原因是下面的流程動作需等回傳完資料後再進行處理。

    2015年12月20日 下午 02:30
  • 我想小朱的意思是... List<object> 最好改成類似 List<employee> , 把object 改為明確有意義的viewmodel 的object會比較好

    微軟免費線上課程

    HTML5 & JavaScript程式開發實戰(MyBook)

    開發ASP.NET您要瞭解的基楚

    http://www.dotblogs.com.tw/ian (MyBlog)

    2015年12月20日 下午 03:48
    版主
  • 喔喔,了解,感謝。

    那要用wait的話是不是只能用task<list<xxx>> ...的方式使用呢?

    2015年12月21日 上午 04:00