2016-12-11 8 views
0

キャンセルボタンをクリックすると、非同期/呼び出し待ちの呼び出しをキャンセルできません。グリッドにデータをロードするのに時間がかかる場合は、クエリをキャンセルしたいと思います。私は非同期/待機メソッドを使用して、多くの例を参照して新しいですが、場合は、トレーニングができません。喜んで私の下のコードを見て、助けてください。ありがとうキャンセルすることができません非同期/呼び出し待ちボタンクリック

namespace MyFirstAsync 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 
     CancellationTokenSource cts ; 
     private async void btnExecute_Click(object sender, EventArgs e) 
     { 
      cts = new CancellationTokenSource(); 
      try 
      { 
       string connectionString = "Data Source=G50-80;Initial Catalog=HPSF_Compdb;User ID=sa;[email protected]"; 
       string sqlQuery = "select top 900000 * from requestevent.result"; 
       SqlConnection conn = new SqlConnection(connectionString); 
       SqlCommand cmd = new SqlCommand(sqlQuery, conn); 
       await conn.OpenAsync(cts.Token); 
       SqlDataReader reader = await cmd.ExecuteReaderAsync(cts.Token); 
       DataTable dt = new DataTable(); 
       //cts.Cancel(); 
       await Task.Run(() => dt.Load(reader), cts.Token); 
       gvData.Invoke(new gvDelegate(UpdateDataToGrid), new object[] { dt }); 
      } 
      catch (Exception ex) 
      { 
       MessageBox.Show(ex.Message); 
      } 

     } 

     public delegate void gvDelegate(DataTable dt); 
     public void UpdateDataToGrid(DataTable dt) 
     { 
      gvData.DataSource = dt; 
     } 



     private void btncancel_Click(object sender, EventArgs e) 
     { 
      cts.Cancel(); 
     } 



    } 
} 
+2

だから何が起こるのあなたは、このコードを実行すると?例外はありますか?あなたが提供する詳細が高いほど、あなたの質問に答えられる可能性が高くなります。 –

+0

こんにちはRuben、いいえ、それはエラーを投げていない、ちょうど完了したクエリとデータをキャンセル要求を受け入れずにグリッドビューにロードしました。私はそれをデバッグする方法とトラブルシュートを知らない。 –

答えて

-1

上記の問題の解決策を見つけただけで、データ読み込み方法をデータテーブルに変更しました。 Plsは新しいコードで置き換えられたコメント付きの古いコードを参照し、期待どおりに優れています。新しいコード私はちょうどコピーして貼り付けるだけで、まだ私はこれについて新しいものとして新しいコードをどのように記述するのかわかりません。しかし、それは私のために働いています。両方を区別すると誰かを説明してください。

using (CancellationTokenRegistration ctr = cts.Token.Register(() => cmd.Cancel())) 
      { 
       using (var reader = cmd.ExecuteReaderAsync(cts.Token)) 
       { 
        dt.Load(reader.Result); 
       } 
      } 
      //SqlDataReader reader = await cmd.ExecuteReaderAsync(cts.Token); 
      //DataTable dt = new DataTable(); 
      //await Task.Run(() => dt.Load(reader), cts.Token); 
+0

私はこのソリューションをStackoverflow以外で見つけました。あなたの質問に答えられる素晴らしい場所です。 :) http://stackoverflow.com/questions/39166619/will-this-cancel-an-executereaderasync –

0

問題のコード行である:あなたが期待するかもしれないものに反して

await Task.Run(() => dt.Load(reader), cts.Token); 

Task.Runに渡さCancellationTokenは、そのタスクではなく、タスク自体のを開始をキャンセルします。つまり、Loadが開始されると、キャンセルすることはできません。

理想的には、現代のコードではDataTableのもの以外を使用する必要があります。キャンセルをサポートするために他のデータベースAPIが更新されました。これが不可能な場合は、答えとしてCancellationTokenRegistrationを使用することができます。ただし、Resultを使用しないで必要があります - 代わりにawaitを使用します。

using (CancellationTokenRegistration ctr = cts.Token.Register(() => cmd.Cancel())) 
using (var reader = await cmd.ExecuteReaderAsync(cts.Token)) 
    dt.Load(reader); 
関連する問題