2

Мои рабочие процессы размещены в IIS. и каждый рабочий процесс наследуется от asynccodeactivity. В BeginExecute я вызываю команду.Beginxxx и в конце выполняю вызов EndExecutexxx. Я использую блок доступа к базе данных (DAAB).операции async DB

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

Идентификатор процесса: 7140

Исключение: System.AggregateException

Сообщение: исключение (ы) задача не наблюдалось ни путем ожидания заданий или доступа к свойству Exception. В результате незаметное исключение было восстановлено потоком финализатора.

StackTrace: в System.Threading.Tasks.TaskExceptionHolder.Finalize()

InnerException: Microsoft.AnalysisServices.AdomdClient.AdomdErrorResponseException

Сообщения: Сервер: текущая операция была отменена, потому что другая операция в транзакции не смогли.

StackTrace: в Microsoft.AnalysisServices.AdomdClient.AdomdConnection.XmlaClientProvider.Microsoft.AnalysisServices.AdomdClient.IExecuteProvider.ExecuteTabular (поведение CommandBehavior, ICommandContentProvider ContentProvider, AdomdPropertyCollection commandProperties, параметры IDataParameterCollection) в Microsoft.AnalysisServices.AdomdClient.AdomdCommand.ExecuteReader (поведение CommandBehavior) в WorkflowActivity.AsyncExecuteSafeReader.ExecuteMdxQuery (String connectionStringName, струнного 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: \ в \ 69 \ Источники \ Инфраструктура \ WorkflowActivity \ AsyncExecuteSafeReader.cs: строка 239 в WorkflowActivity. AsyncExecuteSafeReader. <> c__DisplayClassd.b__a() in d: \ B \ 69 \ Sources \ Infrastructure \ WorkflowActivity \ AsyncExecuteSafeReader.cs: строка 180 в System.Threading.Tasks.Task`1.InvokeFuture (Object futureAsObj) в System.Threading. Tasks.Task.Execute()

+1

Вы используете небезопасный код на разных потоках.Я подозреваю, что он сосредоточен здесь «EnterpriseLibraryContainer.Current.GetInstance», если он не хранит экземпляр для каждой нити. Вам нужно будет проверить код или документы. Во всяком случае, в рамках метода вы должны использовать только «новые» экземпляры, а не переменные класса. – Will

+0

Спасибо. Я проверю, что происходит. но в beginexecute я использую новые экземпляры переменных правильно? или я не понимаю? dbcommand, соединения и объекты базы данных? – KaSh

+1

Пока вы используете ключевое слово 'new', да. – Will

ответ

0

@Will, Похоже, Mars = false в строке соединения разрешил его. не смогли воспроизвести его. theory is - результат запроса. и был вызван конец выполнения. но он также возвратил еще один набор результатов? поэтому был вызван обратный вызов. но конец выполнения уже был вызван к тому времени. Но опять же, это спорадично. Если эта теория верна, то я понимаю, что она могла не работать все время. До сих пор не удалось вообще сбой. было также несколько процедур, которые имели ряд. Я благодарен, что вы потратили время, чтобы прокомментировать и поделиться своей теорией. многому научился.

2

Первый намек на то, что это происходит в IIS. Хотя обычно это ясно в приложении, когда вы, возможно, сталкиваетесь с проблемами, вызванными многопоточным, это не так в IIS.

Каждый запрос в IIS обслуживается другой нитью. Любые общие экземпляры будут поражены несколькими потоками. Это часто бывает плохой новостью, если вы этого не ожидаете.

Итак, моя первая догадка (должна была угадать, потому что стек вызовов исключений был обрезан, а позже) - то, что вы используете небезопасный код для разных потоков. Я подозревал, что он был сосредоточен здесь EnterpriseLibraryContainer.Current.GetInstance becasue, если он не хранит экземпляр в потоке, он будет совместно использовать один и тот же экземпляр между потоками. Вам нужно будет проверить код или документы. Самый простой способ проверить, что использовать «make object ID» в окне просмотра, а затем сравнить результаты с EnterpriseLibraryContainer.Current.GetInstance в двух разных потоках.

Что было ясно, что ваше исключение было заблудиться, потому что вы были повторно метанием исключения, а не позволяя ему идти. Для получения дополнительной информации о передовой практике в этой ситуации, see this answer.

Повторная проверка стека вызовов по-прежнему оказалась многопоточной ошибкой, однако оказалось, что проблема заключалась в том, что несколько потоков пытались выполнить выполнение двух разных Task.

Сообщение: Операция завершена.
StackTrace: в System.Activities.AsyncOperationContext.ShouldComplete()
(надрез)

Что-то где-то пытается завершить выполнение Task но это уже завершена. Как и в случае, один поток бил другой, завершая асинхронную операцию.

На данный момент невозможно было определить, какова была фактическая проблема и где она происходила без полной следы стека исключения. Лучший способ получить эту информацию - поймать исключение с первой вероятностью в вашем коде и вызвать на нем ToString() или использовать ссылку «копировать в буфер обмена» в диалоговом окне помощника исключения (делает то же самое, копирует его на буфер обмена). Это очень важно, потому что вы получите следующую информацию

  1. Тип исключения
  2. Сообщение об исключении
  3. Стек след

НЕ ТОЛЬКО за исключением вы поймали, но каждый .InnerException обернут этим исключением ! ` Часто вот где ваша настоящая проблема скрыта.

И в этом случае, когда вы это сделали, вы смогли определить, где ваш код испытывает проблемы с повторной установкой.

+0

Спасибо. Я не смог вставить всю ошибку. Я сделал и tostring, и бросил. и имеют ошибки. вы правы в другой задаче, которая пытается завершить что-то, что уже завершено. найти это стало кошмаром. Я использую ASyncNativeactivity codeplex и наследую, что для выполнения асинхронных операций с db.lot ошибок, похоже, возникает запрос из используемого класса (который является наследованием от асинхронного). моя проблема в том, что я не могу вставить больше определенных символов здесь. но попробуй еще раз проконсультироваться и прокомментировать здесь как можно скорее – KaSh

+0

@kavya, вы можете отредактировать свой вопрос, чтобы заменить исключение, которое у вас есть в настоящее время. – Will

+0

супер. Я сделал это. есть несколько мест, где я получаю ошибку. одно из мест - это то, что я изменил выше. ТОБЕГИН продолжал. Итак, насколько я понимаю, он не должен был давать ошибку, которую я только что редактировал? – KaSh