increase commandtimeout c# dataset timeout command

c# - commandtimeout - ¿Cómo puedo cambiar el tiempo de espera del comando del adaptador de mesa?



connection timed out c# (13)

Ampliando las respuestas ya muy útiles para tableadapters que me ayudaron mucho, también tuve la necesidad de leer el valor del tiempo de espera real. Así:

namespace XTrans.XferTableAdapters { public partial class FooTableAdapter { int? _timeout = null; ///<summary> ///Get or set the current timeout in seconds for Select statements. ///</summary> public int CurrentCommandTimeout { get { int timeout = 0; if (_timeout != null) { timeout = (int)_timeout; } else { for (int i = 0; i < this.CommandCollection.Length; i++) if (this.CommandCollection[i] != null) timeout = this.CommandCollection[i].CommandTimeout; } return timeout; } set { if (this.CommandCollection == null) this.InitCommandCollection(); for (int i = 0; i < this.CommandCollection.Length; i++) if (this.CommandCollection[i] != null) { this.CommandCollection[i].CommandTimeout = value; _timeout = value; } } } } }

Estoy usando Visual Studio 2008 con C #.

Tengo un archivo .xsd y tiene un adaptador de mesa. Quiero cambiar el tiempo de espera del comando del adaptador de mesa.

Gracias por tu ayuda.


Aquí hay un código de ejemplo de MSDN , usando VB.NET:

Imports System.Data.SqlClient Namespace MyDataSetTableAdapters Partial Class CustomersTableAdapter Public Sub SetCommandTimeOut(ByVal timeOut As Integer) For Each command As SqlCommand In Me.CommandCollection command.CommandTimeout = timeOut Next End Sub End Class End Namespace

Cuando llegue el momento de llamar a una consulta larga, simplemente llame al método SetCommandTimeOut antes de la consulta:

Dim ds As New MyDataSet Dim customersTA As New MyDataSetTableAdapters.CustomersTableAdapter '' Increase time-out to 60 seconds customersTA.SetCommandTimeOut(60000) '' Do the slow query customersTA.FillSlowQuery(ds.Customers)


Con algunas pequeñas modificaciones la idea de csl funciona muy bien.

partial class FooTableAdapter { /** * <summary> * Set timeout in seconds for Select statements. * </summary> */ public int SelectCommandTimeout { set { for (int i = 0; i < this.CommandCollection.Length; i++) if (this.CommandCollection[i] != null) this.CommandCollection[i].CommandTimeout = value; } } }

Para usarlo, simplemente configura this.FooTableAdapter.CommandTimeout = 60; En algún lugar antes de this.FooTableAdapter.Fill ();

Si necesita cambiar el tiempo de espera en una gran cantidad de adaptadores de mesa, puede crear un método de extensión genérico y hacer que use la reflexión para cambiar el tiempo de espera.

/// <summary> /// Set the Select command timeout for a Table Adapter /// </summary> public static void TableAdapterCommandTimeout<T>(this T TableAdapter, int CommandTimeout) where T : global::System.ComponentModel.Component { foreach (var c in typeof(T).GetProperty("CommandCollection", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetProperty | System.Reflection.BindingFlags.Instance).GetValue(TableAdapter, null) as System.Data.SqlClient.SqlCommand[]) c.CommandTimeout = CommandTimeout; }

Uso:

this.FooTableAdapter.TableAdapterCommandTimeout(60); this.FooTableAdapter.Fill(...);

Esto es un poco más lento. Y existe la posibilidad de un error si lo usa en el tipo de objeto incorrecto. (Hasta donde sé, no existe una clase de "TableAdapter" a la que pueda limitarse).


Digamos que su conjunto de datos se llama MySET.
Hay una tabla llamada MyTable

MySETTableAdapters.MyTableTableAdapter fAdapter = new MySETTableAdapters.MyTableTableAdapter(); fAdapter.Adapter.SelectCommand.CommandTimeout = <fill inyour value here>;


En algunos casos, no puede acceder a miembros como Adapter en su clase, ya que están definidos como privados para la clase.

Afortunadamente, el asistente generará clases parciales, lo que significa que puede ampliarlas. Como se describe en [este hilo por Piebald] [1], puede escribir su propia propiedad para establecer el tiempo de espera en los comandos de selección.

En general, harías esto:

partial class FooTableAdapter { /** * <summary> * Set timeout in seconds for Select statements. * </summary> */ public int SelectCommandTimeout { set { for ( int n=0; n < _commandCollection.Length; ++n ) if ( _commandCollection[n] != null ) ((System.Data.SqlClient.SqlCommand)_commandCollection[n]) .commandTimeout = value; } } }

Tenga en cuenta que no lo he intentado, pero parece una solución viable.


Este es un poco viejo ahora y sospecho que esta solución no es relevante para todos, pero he terminado usando solución para anular el control ObjectDataSource de la siguiente manera:

public class MyObjectDataSource : ObjectDataSource { public MyObjectDataSource() { this.ObjectCreated += this.MyObjectDataSource_ObjectCreated; } private void MyObjectDataSource_ObjectCreated(object sender, ObjectDataSourceEventArgs e) { var objectDataSourceView = sender as ObjectDataSourceView; if (objectDataSourceView != null && objectDataSourceView.TypeName.EndsWith("TableAdapter")) { var adapter = e.ObjectInstance; PropertyInfo adapterProp = adapter.GetType() .GetProperty( "CommandCollection", BindingFlags.NonPublic | BindingFlags.GetProperty | BindingFlags.Instance); if (adapterProp == null) { return; } SqlCommand[] commandCollection = adapterProp.GetValue(adapter, null) as SqlCommand[]; if (commandCollection == null) { return; } foreach (System.Data.SqlClient.SqlCommand cmd in commandCollection) { cmd.CommandTimeout = 120; } } } }


Hoy he investigado un poco este problema y he encontrado la siguiente solución basada en algunas fuentes. La idea es crear una clase base para que el adaptador de tabla también herede, lo que aumenta el tiempo de espera para todos los comandos en el adaptador de tabla sin tener que volver a escribir demasiado código existente. Tiene que usar la reflexión ya que los adaptadores de tabla generados no heredan nada útil. Expone una función pública para alterar el tiempo de espera si desea eliminar lo que usé en el constructor y usarlo.

using System; using System.Data.SqlClient; using System.Reflection; namespace CSP { public class TableAdapterBase : System.ComponentModel.Component { public TableAdapterBase() { SetCommandTimeout(GetConnection().ConnectionTimeout); } public void SetCommandTimeout(int Timeout) { foreach (var c in SelectCommand()) c.CommandTimeout = Timeout; } private System.Data.SqlClient.SqlConnection GetConnection() { return GetProperty("Connection") as System.Data.SqlClient.SqlConnection; } private SqlCommand[] SelectCommand() { return GetProperty("CommandCollection") as SqlCommand[]; } private Object GetProperty(String s) { return this.GetType().GetProperty(s, BindingFlags.NonPublic | BindingFlags.GetProperty | BindingFlags.Instance).GetValue(this, null); } } }


Llame a la función ChangeTimeout proporcionando el TableAdapter y el tiempo en segundos.

this.ChangeTimeout(this.taTest, 500);

Función:

private void ChangeTimeout(Component component, int timeout) { if (!component.GetType().FullName.Contains("TableAdapter")) { return; } PropertyInfo adapterProp = component.GetType().GetProperty("CommandCollection", BindingFlags.NonPublic | BindingFlags.GetProperty | BindingFlags.Instance); if (adapterProp == null) { return; } SqlCommand[] command = adapterProp.GetValue(component, null) as SqlCommand[]; if (command == null) { return; } Interaction.command(0).CommandTimeout = timeout; }


Me gusta esto Haga clic derecho en Fill() o GetX() y haga clic en Goto Defination desde el menú.

Verás el código fuente de DATATABLE. Y encontrar ;

private global::System.Data.SqlClient.SqlCommand[] _commandCollection;

línea de comando desde su clase de adaptador de datos. Y cambiar lo privado a público.

Ahora puede acceder a _commandCollection y puede cambiar todos los atributos.

Pero tenga cuidado cuando agregue o modifique cualquier DESIGNER de formulario archivado, el público será privado nuevamente por el sistema autogenerado.

Y también, cuando termine de llamar a la función Rellenar u Obtener, debe restablecer _commandColleciton llamando a esta función ( InitCommandCollection() )

public void InitCommandCollection() {}

Esta función también es privada por autogen, ¡debe cambiar a público también!

Ejemplo:

dsIslemlerTableAdapters.tblIslemlerTableAdapter _t = new dsIslemlerTableAdapters.tblIslemlerTableAdapter(); dsIslemler.tblIslemlerDataTable _m = new dsIslemler.tblIslemlerDataTable(); _t._commandCollection[0].CommandText = "Select * From tblIslemler Where IslemTarihi>='''' And IslemTarihi<=''''"; _m = _t.GetData(); _t.InitCommandCollection();


Parece que hay una manera más conveniente de hacer esto. Aquí hay un resumen rápido de lo que encontré.

Digamos que agrego un proyecto (biblioteca de clases) llamado MyDB a mi solución. En ese proyecto agrego un DataSet llamado "Datos". Y en ese conjunto de datos, arrastro una tabla llamada "X".

Lo que obtengo en la superficie de diseño es un objeto que muestra que tengo un objeto llamado "XTableAdapter".

Ahora abro el código generado, Data.Designer.cs, y busco XTableAdapter. Cuando lo encuentro, observo que está contenido en el espacio de nombres MyDB.DataTableAdapters, que es solo una concatenación del nombre del proyecto, "MyDB", el nombre del DataSet, "Data" y "TableAdapters".

Con eso en la mano, ahora vuelvo a la biblioteca de clases, todavía llamada Class1.cs (que ignoraré por ahora).

Cambio su espacio de nombres de MyDB a MyDB.DataTableAdapters.

Cambié la declaración de la clase a una clase parcial pública XTableAdapter , y hago que se vea así:

using System.Data.SqlClient; namespace MyDB.DataTableAdapters { public partial class XTableAdapter { public void SetTimeout(int seconds) { foreach (SqlCommand cmd in CommandCollection) { cmd.CommandTimeout = seconds; } } } }

La secuencia de llamada difícilmente podría ser más clara:

int TwoMinutes = 120; XTableAdapter.SetTimeout(TwoMinutes);

Menos muss, menos alboroto, menos reflexión (bueno, ninguno), menos relleno.


Puede abrir la carpeta Propiedades, abrir Settings.settings y modificar la propiedad Tiempo de espera de su cadena de conexión.


Si usas una clase parcial, haz que tengas el espacio de nombres correcto. Probablemente [el nombre de su conjunto de datos] + "TableAdapters ''. Ejemplo:

espacio de nombres MyProject.DataSet1TableAdapters


Tuve un par de problemas con el uso de la solución de Mitchell Gilman que finalmente pude solucionar.

En primer lugar, necesitaba asegurarme de usar el espacio de nombres correcto. Me tomó un tiempo descubrir que el archivo del Diseñador para el conjunto de datos xsd contiene dos espacios de nombres, uno para el conjunto de datos en general y otro para los adaptadores de tabla. Por lo tanto, lo primero que se debe tener en cuenta es que se debe usar el espacio de nombres para el adaptador de tabla, no para el conjunto de datos en general.

En segundo lugar, la colección de comandos no siempre se puede inicializar cuando se usa el comando de tiempo de espera por primera vez. Para solucionar esto, llamé al comando InitCommandCollection si este fuera el caso.

Así que la solución adaptada que utilicé fue

namespace xxx.xxxTableAdapters partial class FooTableAdapter { /** * <summary> * Set timeout in seconds for Select statements. * </summary> */ public int SelectCommandTimeout { set { if (this.CommandCollection == null) this.InitCommandCollection(); for (int i = 0; i < this.CommandCollection.Length; i++) if (this.CommandCollection[i] != null) this.CommandCollection[i].CommandTimeout = value; } } }

Espero que sea útil para las personas!