【问题标题】:Entity Framework and roaming WiFi connection drops实体框架和漫游 WiFi 连接断开
【发布时间】:2018-06-12 02:22:13
【问题描述】:

对于我遇到的问题,我的想法已经不多了。我编写了一个在 Windows 平板电脑上运行的应用程序,它通过 WiFi 连接到数据库 (SQL)。我们有几个室外 WiFi 点(Ubiquity)。每个 AP 的 SSID 相同,并且平板电脑将交换 AP(有时它们会保留较弱的 AP,而不是交换到较强的 AP)。

有时这种 AP 的交换或者如果它保持弱信号 EF 将在任何数据库操作上超时。它抛出的异常类型为:

EntityCommandExecutionException

EntityException

与后者:

=====MESSAGE=====
An error occurred while executing the command definition. See the inner exception for details.
=====STACK=====
   at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
   at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlan.Execute[TResultType](ObjectContext context, ObjectParameterCollection parameterValues)
   at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass7.<GetResults>b__6()
   at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
   at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass7.<GetResults>b__5()
   at System.Data.Entity.Infrastructure.DbExecutionStrategy.Execute[TResult](Func`1 operation)
   at System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
   at System.Data.Entity.Core.Objects.ObjectQuery`1.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__0()
   at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()
   at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source)
   at WarehousePicking.MainForm.buttonScan_Click(Object sender, EventArgs e) in C:\Users\tiwainski\Documents\Visual Studio 2017\Projects\WE\LIBRARIES\warburn-estate-library\WarehousePicking\MainForm.cs:line 335
   at System.Windows.Forms.Control.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnClick(EventArgs e)
   at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ButtonBase.WndProc(Message& m)
   at System.Windows.Forms.Button.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
=======INNER=====
A transport-level error has occurred when receiving results from the server. (provider: TCP Provider, error: 0 - The semaphore timeout period has expired.)
=======STACK=====
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObject stateObj, UInt32 error)
   at System.Data.SqlClient.TdsParserStateObject.ReadSniSyncOverAsync()
   at System.Data.SqlClient.TdsParserStateObject.TryReadNetworkPacket()
   at System.Data.SqlClient.TdsParserStateObject.TryPrepareBuffer()
   at System.Data.SqlClient.TdsParserStateObject.TryReadByte(Byte& value)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData()
   at System.Data.SqlClient.SqlDataReader.get_MetaData()
   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
   at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds, Boolean describeParameterEncryptionRequest)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite)
   at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
   at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
   at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<Reader>b__c(DbCommand t, DbCommandInterceptionContext`1 c)
   at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
   at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext)
   at System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader(CommandBehavior behavior)
   at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
   at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
=======INNER=====
The semaphore timeout period has expired
=======STACK=====

我的上下文也配置了以下

  SetTransactionHandler(SqlProviderServices.ProviderInvariantName, () => new CommitFailureHandler());
    SetExecutionStrategy(SqlProviderServices.ProviderInvariantName, () => new SqlAzureExecutionStrategy(10, System.TimeSpan.FromSeconds(3)));

编辑: 即使使用当前的执行策略,我偶尔也会遇到超时。

是否可以将 EF 配置为自动切换到本地数据库并在网络中断的情况下保存上下文? 还是我必须手动处理,例如使用自定义执行策略?

在这两种情况下,EF 是否能够同步两个数据库或自动将数据库 A 合并到数据库 B 中,还是我需要编写迁移脚本?

【问题讨论】:

    标签: c# database entity-framework


    【解决方案1】:

    查看执行策略及其配置。默认情况下,EF 使用 DefaultDbExecutionStrategy,它不会重试,但会在失败的情况下发送异常。

    DbExecutionStrategy 可以扩展以包含任何检查和重试条件过滤,从而为连接在引发异常之前重试操作的方式提供相当大的灵活性。

    查看 EF 连接弹性:https://msdn.microsoft.com/en-us/library/dn456835(v=vs.113).aspx

    【讨论】:

    • 正如在最初的帖子中提到的,我确实改变了执行策略,它实际上设置为以 3 秒的间隔尝试 10 次,但是我仍然不时收到这些异常。最坏的情况是网络已关闭.. EF 可以处理它并切换到本地数据库连接还是必须手动? -- 将编辑我的原始帖子
    猜你喜欢
    • 2012-03-13
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 2011-04-08
    • 2020-11-18
    • 2011-07-29
    • 1970-01-01
    相关资源
    最近更新 更多