c# - 如何手动关闭与数据库的连接并取消在后台进程中运行的查询数据?
问题描述
我有使用BackgrwoundWorker
.
public partial class MainForm : Form, IDataFetcher
{
public EntryForm EntryForm { get; set; }
public ApplicationSettings Settings { get; set; }
private DbDataBackgroundWorker BackgroundWorker { get; set; }
enum QueryStatus { RUNNING, NOT_STARTED }
private QueryStatus;
public BillingForm()
{
InitializeComponent();
// configure background actual opearations
BackgroundWorker = new OpearationBackgroundWorker()
{
OnDataFetch = OnDataFetch,
OnDataFetchCompleted = OnDataFetchCompleted
};
}
public BillingForm(EntryForm parentForm, ApplicationSettings appSettings) : this()
{
EntryForm = parentForm;
Settings = appSettings;
queryStatus = QueryStatus.NOT_STARTED;
}
private void ExecuteButton_Click(object sender, EventArgs e)
{
switch (queryStatus)
{
case QueryStatus.NOT_STARTED:
BackgroundWorker.Start();
break;
case QueryStatus.RUNNING:
BackgroundWorker.Stop();
break;
}
}
public void OnDataFetchCompleted(object sender, RunWorkerCompletedEventArgs e)
{
queryStatus = QueryStatus.NOT_STARTED;
if (e.Error != null)
{
MessageBox.Show(e.Error.Message, Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
public void OnDataFetch(object sender, DoWorkEventArgs e)
{
var worker = sender as BackgroundWorker;
if (worker.CancellationPending)
{
e.Cancel = true;
//MessageBox.Show("Запрос остановлен");
return;
}
// create database handler
var db = new DatabaseConnector(Settings.DbConnectionString);
var model = new BillingModel(db)
{
PostTitle = PostTitle,
StartDate = StartDateTimePicker.Value,
EndDate = EndDateTimePicker.Value,
};
try
{
model.Query((datatable) =>
{
Invoke(new Action(() =>
{
QueryResultDataGridView.DataSource = null;
QueryResultDataGridView.DataSource = datatable;
}));
});
}
catch (Exception exception)
{
Invoke(new Action(() => {
queryStatus = QueryStatus.NOT_STARTED;
}));
}
}
}
当我单击“开始”按钮(方法ExecuteButton_Click
)时,程序会在后台获取数据并将它们放入DataGridView
.
// this class starts operations in background
public class OpearationBackgroundWorker
{
public Action<object,DoWorkEventArgs> OnDataFetch { get; set; }
public Action<object, RunWorkerCompletedEventArgs> OnDataFetchCompleted { get; set; }
//public Action<object, ProgressChangedEventArgs> OnDataFetchProgress { get; set; }
private BackgroundWorker backgroundWorker = new BackgroundWorker()
{
WorkerSupportsCancellation = true
};
public void Start()
{
backgroundWorker.DoWork += new DoWorkEventHandler(OnDataFetch);
backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(OnDataFetchCompleted);
if ( !backgroundWorker.IsBusy )
backgroundWorker.RunWorkerAsync();
else
throw new Exception("Process running!");
}
public void Stop()
{
backgroundWorker.CancelAsync();
backgroundWorker.Dispose();
}
}
public class SimpleModel : AbstractModel
{
public IDatabaseFetcher Db { get; set; }
public string PostTitle { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public BillingModel(IDatabaseFetcher db)
{
Db = db;
}
public override void Query(Action<DataTable> callback)
{
var query = "SELECT * FROM posts WHERE post_titile = " + PostTitle;
Db.Query = query;
Db.Fetch(data => callback(data));
}
}
该程序使用 C#using
构造来自动处理数据库连接。
public interface IDataFetcher
{
void OnDataFetch(object sender, DoWorkEventArgs e);
void OnDataFetchCompleted(object sender, RunWorkerCompletedEventArgs e);
}
class DatabaseConnector : IDatabaseFetcher
{
private string connectionString = "";
public string Query { get; set; }
public DatabaseConnector(string connectionString)
{
this.connectionString = connectionString;
}
// here i query data from db
public void Fetch(Action<DataTable> action)
{
using (var connection = new OracleConnection(connectionString))
using (var cmd = new OracleCommand(Query, connection))
{
connection.Open();
using (var reader = cmd.ExecuteReader())
{
if (!reader.HasRows)
{
throw new Exception("Empty result!");
}
var dataTable = new DataTable();
dataTable.Load(reader);
// run callback processor
action(dataTable);
}
}
}
}
但现在,我想稍微改变程序的行为,并添加手动取消操作的能力,并关闭与数据库的连接。
我已经知道如何取消BackgrwoundWorker
执行,但是当用户单击“停止”按钮时,我找不到如何手动关闭与数据库的连接并取消查询在后台进程中运行的数据的解决方案。
这个怎么做?
解决方案
推荐阅读
- apache-spark - 将 java 连接到 Apache Spark Sql
- r - R 中的 sens.slope() 与 mblm()
- sql - Postgres:查找具有最大值的行
- html - 如何修复悬停效果
- java - java - 如何将具有相同功能的多个iso日期格式转换为java中的日期?
- ubuntu - cpuinfo 和 htop 的区别
- javascript - 你好,我想得到一个所有符号都是小写的字符串。代码不想工作,我不明白我在哪里会出错
- c++ - C++/SFML 超级马里奥游戏与块的碰撞问题
- angular - Ionic 4/Angular 以原子方式打开默认选项卡
- laravel - 从表单按钮浏览服务器上的图像,就像上传图像时一样