我的工作流程托管在IIS中。并且每个工作流都继承自asynccodeactivity。在BeginExecute中,我调用command.Beginxxx,最后执行i调用EndExecutexxx。我正在使用数据库访问块(DAAB)。
protected override IAsyncResult BeginExecute(AsyncCodeActivityContext context, AsyncCallback callback, object state)
{
DbCommand command = null;
DbConnection dbConnection = null;
entlib.Database database;
try
{
database = EnterpriseLibraryContainer.Current.GetInstance<entlib.Database>(DatabaseName.Get(context));
dbConnection = database.CreateConnection();
command = dbConnection.CreateCommand();
command.CommandText = CommandText.Get(context);
command.CommandType = CommandType.Get(context);
//have removed few assignments here
context.UserState = new AsyncDbState(database, command);
}
catch (Exception e)
{
if (command != null)
command.Dispose();
if (dbConnection != null)
dbConnection.Dispose();
throw e;
}
return (database.Beginxxx(command, callback, state));
}
protected override TResult EndExecute(AsyncCodeActivityContext context, IAsyncResult iResult)
{
TResult result = default(TResult);
var userState = context.UserState as AsyncDbState;
try
{
result = (TResult)userState.Database.Endxxx(iResult);
}
finally
{
if (null != userState && null != userState.Command)
userState.Command.Dispose();
}
return result;
}
偶尔会在事件日志中抛出错误并终止整个应用程序池。 在@Will发表评论之后,我确实陷入了内部异常并注意到实际发生的错误
在不同活动的BeginExecute中,继承自asyncnativeactivity,我有
var task = AsyncFactory<IDataReader>.Action(() => ExecuteMdxQuery(connectionStringSettings, mdxQuery, commandTimeout, cancellationToken), cancellationToken);
return AsyncFactory<IDataReader>.ToBegin(task, callback, state);
and AsyncFactory looks like this
public static Task<TResult> Action(Func<TResult> actionMethod,CancellationToken token)
{
TaskFactory factory = new TaskFactory();
//TaskFactory factory = new TaskFactory(scheduler);
return factory.StartNew<TResult>(() => actionMethod(), token);
}
public static IAsyncResult ToBegin(Task<TResult> task, AsyncCallback callback, object state)
{
var tcs = new TaskCompletionSource<TResult>(state);
var continuationTask = task.ContinueWith(t =>
{
if (task.IsFaulted)
{
tcs.TrySetException(task.Exception.InnerExceptions);
}
else if (task.IsCanceled)
{
tcs.TrySetCanceled();
}
else
{
tcs.TrySetResult(task.Result);
}
发生了未处理的异常,并且该过程已终止。
发生了未处理的异常,并且该过程已终止。
申请ID:/ LM / W3SVC / 1 / ROOT / workflowservice
流程ID:7140
异常:System.AggregateException
消息:通过等待任务或访问其异常属性,未观察到任务的异常。结果,终结器线程重新抛出了未观察到的异常。
StackTrace:在System.Threading.Tasks.TaskExceptionHolder.Finalize()
InnerException:Microsoft.AnalysisServices.AdomdClient.AdomdErrorResponseException
消息:服务器:当前操作已取消,因为事务中的另一个操作失败。
StackTrace:at Microsoft.AnalysisServices.AdomdClient.AdomdConnection.XmlaClientProvider.Microsoft.AnalysisServices.AdomdClient.IExecuteProvider.ExecuteTabular(CommandBehavior behavior,ICommandContentProvider contentProvider,AdomdPropertyCollection commandProperties,IDataParameterCollection parameters)
在Microsoft.AnalysisServices.AdomdClient.AdomdCommand.ExecuteReader(CommandBehavior行为)
at WorkflowActivity.AsyncExecuteSafeReader.ExecuteMdxQuery(String connectionStringName,String mdxQuery,Nullable 1 commandTimeout, CancellationToken cancellationToken) in d:\B\69\Sources\Infrastructure\WorkflowActivity\AsyncExecuteSafeReader.cs:line 222
at AsyncExecuteSafeReader.ExecuteMdxQuery(String connectionStringName, String mdxQuery, Nullable
1 commandTimeout,CancellationToken cancellationToken)在d:\ B \ 69 \ Sources \ Infrastructure \ WorkflowActivity \ AsyncExecuteSafeReader.cs:第239行
在WorkflowActivity.AsyncExecuteSafeReader。&lt;&gt; c__DisplayClassd.b__a()在d:\ B \ 69 \ Sources \ Infrastructure \ WorkflowActivity \ AsyncExecuteSafeReader.cs:第180行
在System.Threading.Tasks.Task`1.InvokeFuture(Object futureAsObj)
在System.Threading.Tasks.Task.Execute()
答案 0 :(得分:2)
第一个提示是这种情况发生在IIS中。虽然在您可能遇到由多线程引起的问题时,应用程序通常会清楚,但在IIS中并非如此。
IIS中的每个请求都由不同的线程提供服务。任何共享实例都会受到多个线程的攻击。如果你不期待它,这往往是坏消息。
所以我的第一个猜测(不得不猜测,因为你的异常调用堆栈被切断了;后面会有更多内容)是你在不同的线程中使用线程不安全的代码。我怀疑它集中在EnterpriseLibraryContainer.Current.GetInstance
,因为如果它不存储每个线程的实例,它将在线程之间共享相同的实例。您必须检查代码或文档。最简单的测试方法是使用&#34;制作对象ID&#34;在观察窗口中,然后在两个不同的线程中比较EnterpriseLibraryContainer.Current.GetInstance
的结果。
有关此情况下最佳做法的详细信息,请see this answer。
重新检查调用堆栈,它似乎仍然是一个多线程错误,但似乎问题是多个线程试图完成两个不同的Task
的执行。
消息:操作已完成。
StackTrace:在System.Activities.AsyncOperationContext.ShouldComplete()
(剪断)
某处某处正在尝试完成Task
的执行,但它已经完成。就像在,一个线程击败另一个完成异步操作。
此时,如果没有异常的完整堆栈跟踪,就无法确定实际问题是什么以及发生了什么。获取此信息的最佳方法是在代码中第一次捕获异常并在其上调用ToString()
,或使用&#34;复制到剪贴板&#34;异常帮助器对话框上的链接(做同样的事情,将其复制到剪贴板)。这很重要,因为您可以获得以下信息
不仅仅是针对您捕获的异常,而是针对此异常所包含的每个.InnerException
!经常隐藏您的真正问题。< / strong>
而且,在这种情况下,当您这样做时,您就能够确定代码遇到重入问题的位置。
答案 1 :(得分:0)
@Will,看起来连接字符串中的Mars = false已经解决了它。无法复制它。 理论是 - 查询返回结果。和结束执行被调用。但它还返回了另一个结果集?这就是调用回调的原因。但是当时已经调用了end execute。但话说回来,它是零星的。如果这个理论是正确的,我的理解是它可能一直都失败了。 到目前为止还没有崩溃。还有很少有行计数的程序。 我很感激你花时间评论并分享你的理论。我学到了很多东西。