Background:
1. There is a DataSet named MyDataSet, which includes a DataTable namde MyTable and a TableAdapter named MyAdapter.
2. There is a report file named MyReport.rdlc whose DataSource is MyDataSet_MyTable.
3. There is a ReportPage form with an ObjectDataSource named MyDataSource and a ReportViewer named MyRptViewer. MyDataSource links to MyAdapter. MyRptViewer's 'Choose Report' is MyReport.rdlc. MyRptViewer's 'Choose Data Sources' is MyDataSource.
Issue:
When we run this report in the reportviewer and the report is executed in more than 30 seconds, we will meet Timeout Expired issue. It is caused by the CommandTimeout of a TableAdapter. The default value of the CommandTimeout is 30 seconds. If we can extend the CommandTimeout, the report will then work properly.
How to extend the CommandTimeout?
1. Challenge
In the design window of DataSet, we can not find a place where we can set the CommandTimeout for a TableAdapter.
We can set it in MyDataSet.Designer.cs file directly. However, any custom modifications in the MyDataSet.Designer.cs file will be removed when we modify MyDataSet in the design window and save it.
2. Solution
Fortunately, class MyAdapter is a partial class. So we can create another partial class to add our required properties or methods. We need to define the partial class in MyDataSet.cs file in order that both partial classes are under the same compile path. Here are the source codes:
public partial class MyAdapter : global::System.ComponentModel.Component
{
public int CommandTimeout
{
set
{
for (int n = 0; n < this.CommandCollection.Length; n++)
{
if (this.CommandCollection[n] != null)
{
this.CommandCollection[n].CommandTimeout = value;
}
}
}
}
}
Then we need to add ObjectCreated event for the ObjectDataSource.
protected void MyDataSource_ObjectCreated(object sender, ObjectDataSourceEventArgs e)
{
((MyDataSetTableAdapters.MyAdapter)e.ObjectInstance).CommandTimeout = 0;
}
So far, we have finished all custom modifications to extend the CommandTimeout.