- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
SQL版本:SQL Server 2008 R2标准版
应用 : .Net 3.5 (Windows Form)
这是我运行代码后收到的错误
The CLR has been unable to transition from COM context 0xe88270 to COM context 0xe88328 for 60 seconds. The thread that owns the destination context/apartment is most likely either doing a non pumping wait or processing a very long running operation without pumping Windows messages. This situation generally has a negative performance impact and may even lead to the application becoming non responsive or memory usage accumulating continually over time. To avoid this problem, all single threaded apartment (STA) threads should use pumping wait primitives (such as CoWaitForMultipleHandles) and routinely pump messages during long running operations.
以下代码有时会产生上述错误。很可能在插入 24,000 多条记录后出现错误。
代码的目标
编写代码以插入虚拟条目来测试我的应用程序
Random rnd = new Random();
string Data = "";
for (int i = 0; i < 2000000; i++)
{
Data = "Insert Into Table1(Field1)values('" + rnd.Next(0, 200000000) + "');" + Environment.NewLine +
"Insert Into Table1(Field1)values('" + rnd.Next(0, 200000000) + "');" + Environment.NewLine +
"Insert Into Table1(Field1)values('" + rnd.Next(0, 200000000) + "');" + Environment.NewLine +
"Insert Into Table1(Field1)values('" + rnd.Next(0, 200000000) + "');" + Environment.NewLine +
"Insert Into Table1(Field1)values('" + rnd.Next(0, 200000000) + "');" + Environment.NewLine +
"Insert Into Table1(Field1)values('" + rnd.Next(0, 200000000) + "');";
ExecuteQuery(Data);//Error is displayed here
}
“执行查询”的代码
SqlConnection Conn = new SqlConnection("Connection String");
if (Conn == null)
{
Conn = new SqlConnection(Program.ConnString);
}
if (Conn.State == ConnectionState.Closed)
{
Conn.Open();
}
else
{
Conn.Close();
Conn.Open();
}
SqlCommand cmd = new SqlCommand();
cmd.Connection = Conn;
cmd.CommandTimeout = 600000;
cmd.CommandType = CommandType.Text;
cmd.CommandText = strsql;
cmd.ExecuteNonQuery();
Conn.Close();
注意 :- 我在查询中编写了多个完全相同的插入语句,因为它会减少编号。 SQL 必须处理的查询数
问题
我如何优化我的代码以防止错误发生?
最佳答案
"The CLR has been unable to transition from COM context … to COM context … for 60 seconds. The thread that owns the destination context/apartment is most likely either doing a non pumping wait or processing a very long running operation without pumping Windows messages."
从你的问题中你的代码如何工作的细节并不完全清楚,所以我假设你的应用程序不是多线程的,即执行 2×6 百万数据库 INSERT
s 的循环正在运行应用程序的主 (UI) 线程。这可能需要一段时间(> 60 秒),因此您的 UI 将在此期间卡住(即使其无响应)。这是因为当您的(阻塞)循环仍在运行时,Windows 窗体永远没有机会运行并对用户输入使用react。我敢打赌这就是导致您引用警告的原因。
您可以做的第一件简单的事情就是将您的 SqlCommand
变成一个参数化命令。然后,您将使用相同的 SQL 文本发出命令;只有单独提供的参数会有所不同:
private void InsertRandomNumbers(int[] randomNumbers)
{
const string commandText = "INSERT INTO dbo.Table1 (Field1) VALUES (@field1);"
using (var connection = new SqlConnection(connectionString)
using (var command = new SqlCommand(commandText, connection))
{
var field1Parameter = new SqlDataParameter("@field1", SqlDbType.Int);
command.Parameters.Add(field1Parameter);
connection.Open();
foreach (int randomNumber in randomNumbers)
{
field1Parameter.Value = randomNumber;
/* int rowsAffected = */ command.ExecuteNonQuery();
}
connection.Close();
}
}
请注意 commandText
是如何定义为常量的。这是一个很好的迹象,表明 SQL Server 也将始终将其识别为相同的命令——对于参数化命令,实际参数值是单独提供的——SQL Server 只会编译和优化语句一次(并将编译后的语句放入其缓存中所以它可以在以后重复使用)而不是一遍又一遍地做同样的事情。仅此一项就可以节省大量时间。
您可以做的另一件事是将数据库代码转移到后台线程,这样您的应用程序的 UI 就不会卡住。
假设您的数据库INSERT
循环当前由按钮doWorkButton
触发。所以 for
循环在按钮 Click
事件处理程序中:
private void doWorkButton_Click(object sender, EventArgs e)
{
…
for (i = 0; i < 2000000; i++)
{
Data = …
ExecuteQuery(Data);
// note: I leave it as an exercise to you to combine the
// above suggestion (parameterized queries) with this one.
}
}
我们做的第一件事是通过三种方式更改您的 ExecuteQuery
方法:
使其异步。它的返回类型将是 Task
而不是 void
,并且它的声明使用 async
关键字进行扩充。
将其重命名为 ExecuteNonQueryAsync
以反射(reflect)两件事:它现在将是异步的,并且它不执行查询。我们实际上并不期望从数据库 INSERT
中取回结果。
我们重写方法主体以使用 ADO.NET 异步方法而不是同步方法。
这就是它最终可能的样子:
private async Task ExecuteNonQueryAsync(string commandText)
{
using (var connection = new SqlConnection(connectionString)
using (var command = new SqlCommand(commandText, connection))
{
connection.Open();
/* int rowsAffected = */ await command.ExecuteNonQueryAsync();
connection.Close();
}
}
就是这样。现在我们需要修改处理程序方法以使其也异步:
private async void doWorkButton_Click(object sender, EventArgs e)
{
try
{
…
for (i = 0; i < 2000000; i++) { … }
{
Data = …
await ExecuteNonQueryAsync(Data);
}
}
catch
{
… // do not let any exceptions escape this handler method
}
}
这应该处理 UI 卡住业务。
SqlBulkCopy
可以更高效地完成数百万个 INSERT
语句。SQL Server 具有用于批量插入数据的绝妙选项。使用此功能通常会比执行您自己的 INSERT
语句批处理获得更好的性能。
private async void doWorkButton_Click(object sender, EventArgs e)
{
// Prepare the data to be loaded into your database table.
// Note, this could be done more efficiently.
var dataTable = new DataTable();
{
dataTable.Columns.Add("Field1", typeof(int));
var rnd = new Random();
for (int i = 0; i < 12000000; ++i)
{
dataTable.Rows.Add(rnd.Next(0, 2000000));
}
}
using (var connection = new SqlConnection(connectionString))
using (var bulkCopy = new SqlBulkCopy(connection))
{
bulkCopy.DestinationTableName = "dbo.Table1";
try
{
// This will perform a bulk insert into the table
// mentioned above, using the data passed in as a parameter.
await bulkCopy.WriteToServerAsync(dataTable);
}
catch
{
Console.WriteLine(ex.Message);
}
}
}
我现在无法测试,但我希望这能让你开始。如果您想进一步改进基于 SqlBulkCopy
的解决方案,我建议您创建一个 IDataReader
的自定义实现,它创建包含动态随机数据的“行” ,然后将其实例传递给 SqlBulkCopy
而不是预填充的数据表。这意味着您不必在内存中保留一个巨大的数据表,而一次只保留一个数据行。
关于c# Win Form - CLR 无法从 COM 上下文转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40692213/
我的设置.py: LANGUAGE_CODE = 'de' TIME_ZONE = require_env("TIME_ZONE_IDENTIFIER") USE_I18N = True USE_L1
谁能给我解释一下 Django 的 forms.Form 和 forms.ModelForm 的相同点和不同点? 最佳答案 从 forms.Form 创建的表单由您手动配置。您最好将这些用于不直接与模
我在用 angularjs 构建的表单上遇到此错误。 `错误:[$compile:multidir] 多个指令 [form, form] 请求 'form' Controller :
我是 Spring 的新手,在尝试显示表单错误时遇到了一些麻烦。 我有以下表格: User Name:
我希望在提交表单时找出 spring:bind 和 form:form 标记库之间的区别。 我的 JSP 片段如下: ....
类型‘AbstractControl’上不存在属性‘Controls’。
有一个问题与此非常相似,但我想以不同的方式提出。 我是一个非常自定的人,但有时我确实喜欢走捷径。就这样吧。 我确实发现这两个类非常相似,尽管其中一个“帮助”程序员更快地编写代码或减少代码/重复代码。将
我在控制台中收到此错误。 “表单提交已取消,因为表单未连接” 自从我们将应用程序迁移到更新版本的 React 后,尝试将我的 redux-form 从 v5 迁移到 v6 之后。 我不确定这里出了什么
我想要的是一个表单,在提交时运行验证检查,并突出显示所有无效字段并添加工具提示。 我正在有效地寻找这样的东西: dojo.forEach(dijit.byId('myForm')._invalidWi
我需要设置symfony2表单元素的值。 我在 Controller 操作中使用了doctrine2实体, Symfony\Component\Form\AbstractType 和createFor
这是用于将数据提交到自定义列表的自定义 Editform.aspx。用户完成表单后,他应该能够点击按钮甚至“确定”按钮,并让 sharepoint 将表单数据提交到列表,然后重定向到项目显示表单 (d
我想知道在 spring 标签中编写所有表单是否是一种好习惯,或者我可以将 spring 表单标签与 html 表单标签混合使用吗? 最佳答案 当您需要 Spring 表单提供的功能时使用它们: 绑定
我正在构建动态表单并希望“即时”添加表单组。 这是我的代码,几乎可以工作: import {Component, OnInit} from '@angular/core'; import {FormG
表格 Form.Load 有什么区别? , Form.Shown和 Form.Activated事件?他们被解雇的顺序是什么? 最佳答案 参见 Windows Forms Events Lifecyc
我正在使用具有路线跟踪功能的 Xamarin Forms 开发一些应用程序。尽管我正在使用 AppCenter,即在 App.xaml.cs OnStart 我添加 protected asy
我正在实现一个 gameboy 模拟器,就像我之前的许多人一样。 我正在尝试实现 PPU 并为此使用代表屏幕的类。 // needed because VS can't find it as depe
我是 Orbeon Form 新手,想使用它。不过,我尝试过 Orbeon Form 网站上的 Form 示例,并用泰语输入了一些数据。是的,可以在“泰语”字段中输入数据。但是当我尝试生成“PDF”时
那么让表单一遍又一遍有效地呈现相同表单的最佳方法是什么,并根据实体的属性值有条件地禁用字段? 我有一个发票实体,需要一个用于创建发票的表单,以及在发票流程的各个阶段(生成、发送、支付等)禁用各个字段的
因此,我一直在与我的同事(开发人员和设计人员)就 Web 表单的自动填充工具进行亲切的辩论。这是一个重要的开发问题,因为它会影响表单的构建方式。 问)自动填充工具(例如 Google 工具栏或 Chr
那么让表单一遍又一遍有效地呈现相同表单的最佳方法是什么,并根据实体的属性值有条件地禁用字段? 我有一个发票实体,需要一个用于创建发票的表单,以及在发票流程的各个阶段(生成、发送、支付等)禁用各个字段的
我是一名优秀的程序员,十分优秀!