【解決方法】アプリケーションの実行中にこのエラーが発生する理由

[ad_1]

エラー:

Managed Debugging Assistant ‘ContextSwitchDeadlock’: ‘CLR は、COM コンテキスト 0x11a4278 から COM コンテキスト 0x11a41c0 に 60 秒間遷移できませんでした。 宛先コンテキスト/アパートメントを所有するスレッドは、非ポンピング待機を行っているか、Windows メッセージをポンピングせずに非常に長時間実行されている操作を処理している可能性があります。 この状況は通常、パフォーマンスに悪影響を及ぼし、アプリケーションが応答しなくなったり、メモリ使用量が時間の経過とともに継続的に蓄積したりする可能性さえあります。 この問題を回避するには、すべてのシングル スレッド アパートメント (STA) スレッドでポンピング待機プリミティブ (CoWaitForMultipleHandles など) を使用し、実行時間の長い操作中に定期的にメッセージをポンピングする必要があります。

私が試したこと:

C#
private void btnbrowse_Click(object sender, EventArgs e)
{
	OpenFileDialog ofd = new OpenFileDialog();
	ofd.DefaultExt = ".csv";
	ofd.Filter = "Comma Separated (*.csv)|*.csv";
	ofd.ShowDialog();
	txtfilename.Text = ofd.FileName;

	DataTable dt = new DataTable();
	dataGridView1.DataSource = dt.DefaultView;
	{
	  
	}
}
	
private void btnclose_Click(object sender, EventArgs e)
{
	this.Close();
}

private void btnimport_Click(object sender, EventArgs e)
{
	Cursor = Cursors.WaitCursor;

	DataTable dt = GetDataFromFile();

	if (dt == null) return;

	SaveImportDataToDatabase(dt);

	MessageBox.Show("Data Import success!");
	txtfilename.Text = string.Empty;
	Cursor = Cursors.Default;

}

private DataTable GetDataFromFile()
{
	DataTable dt = new DataTable();

	try
	{
		using (StreamReader sr = new StreamReader(txtfilename.Text))
		{
			string header = sr.ReadLine();
			if (string.IsNullOrEmpty(header))
			{
				MessageBox.Show("no file data");
				return null;
			}
			string[] headerColumns = header.Split(',');
			foreach (string headerColumn in headerColumns)
			{
				dt.Columns.Add(headerColumn);
			}

			while (!sr.EndOfStream)
			{
				string line = sr.ReadLine();
				if (string.IsNullOrEmpty(line)) continue;
				string[] fields = line.Split(',');
				DataRow importedRow = dt.NewRow();

				for (int i = 0; i < fields.Count(); i++)
				{
					importedRow[i] = fields[i];
				}
				dt.Rows.Add(importedRow);
				
			}
		}
	}
	catch (Exception e)
	{
		Console.WriteLine("the file could not be read:");
		Console.WriteLine(e.Message);
	}

	return dt;
}
private void SaveImportDataToDatabase(DataTable S2P5)
{
	using (SqlConnection conn =New SqlConnection(@"Data Source=BL03\SQLEXPRESS; Initial Catalog=HDB; User Id=sa; Password=00"))
	{
		conn.Open();

		foreach (DataRow importRow in S2P5.Rows)
		{
			SqlCommand cmd = new SqlCommand ("INSERT INTO S2P5 (DateTime, Miliseconds, MachineAutoStartStop, Pressure)" + 
											 "VALUES (@DateTime, @Miliseconds, @MachineAutoStartStop, @Pressure)", conn);
		  
			cmd.Parameters.AddWithValue("@DateTime", (DateTime)importRow["DateTime"]);
			cmd.Parameters.AddWithValue("@Miliseconds", importRow["Miliseconds"]);
			cmd.Parameters.AddWithValue("@MachineAutoStartStop", importRow["MachineAutoStartStop"]);
			cmd.Parameters.AddWithValue("@Pressure", importRow["Pressure"]);

			cmd.ExecuteNonQuery();
		}
	}
}

解決策 1

ボタン イベント ハンドラから呼び出されたメソッドから大量のデータをデータベースに保存しています。つまり、すべてがメインの UI スレッドで実行されており、SaveImportDataToDatabase メソッドが完了するまで UI イベントを処理できません。 これには非常に長い時間がかかるため、システムは基本的にアプリがフリーズしていると想定しています。

そのコードを BackgroundWorker に移動し、進行状況の更新をメイン スレッドに提供すると、エラーが解消されるはずです。 ただし、プロセスは高速化されません-個々のINSERT操作の代わりにDataAdapterを使用してDBを更新することを検討することをお勧めします-まだバックグラウンドスレッドにあります-しかし、それは進行状況の報告を難しくします.

[ad_2]

コメント

タイトルとURLをコピーしました