2016-09-27 3 views
0

Я понимаю, что ожидание завершает оставшуюся часть исполняемого кода, когда они возвращаются из ожидания. Я пытаюсь заставить это работать в sql clr, и это не работает, поскольку ожидаемый процесс и коды под ним не выполняются. В методе отладки элемент управления просто возвращается после выполнения строки ожидания.SQL CLR awaitable не получается выполненным

Как я могу сделать эту работу, так как требование для clr должно выполняться без блокировки основного потока, так что другая работа может продолжаться и в db. Мне действительно нужно это, чтобы работать, и были на нем в течение 2 дней.

NB Это хорошо работает, если метод синхронизирован. И сохраненный сбор proc зарегистрирован как небезопасный сервер sql. Я использую MSSQL 2012 и Visual Studio 2015.

public partial class StoredProcedures 
{ 
    [Microsoft.SqlServer.Server.SqlProcedure] 
    public static async void sp_push_stock_update(SqlString transactionPrimaryKey, SqlString transactionType) 
    { 

     using (SqlConnection conn = new SqlConnection("context connection=true")) 
     { 

      StockUpdateClient.stock_fetcher _stockFetcher = new StockUpdateClient.stock_fetcher(conn); 

      List<String> skuList = await new 
      System.Threading.Tasks.Task<List<string>>(()=> 
      _stockFetcher.getItems(transactionPrimaryKey, transactionType)); 

      //Code does not get here 
      performLogging(skuList): 


     } 

    } 
} 
+3

Вы никогда не должны использовать 'асинхронной void', если вы пишете обработчик события и' асинхронной Task' [не поддерживается SQLCLR] (https://social.msdn.microsoft.com/Forums/en -US/2f43b23a-ebf7-4f48-9331-654587730d1b/async-and-sqlclr? Forum = async) –

+0

@ScottChamberlain метод по умолчанию недействителен и может быть замечен, когда в проект добавлен новый sql C# clr. Я только украсил его асинхронным, потому что это требование использовать ожидание внутри тела метода, вы говорите, что я могу изменить тип возвращаемого метода? какие другие варианты у меня есть для выполнения асинхронной задачи? –

+1

Для 'SqlProcedure', только два допустимых типа возврата должны быть:' void' и 'SqlInt32'. «SqlInt32» будет возвратным значением (т. Е. «RETURN 5;'), которое может быть записано с использованием: 'DECLARE @ReturnVal INT; EXEC @ReturnVal = dbo.SomeProc; '. –

ответ

1

требование для CLR будет выполняться без блокировки основного потока

вы пробовали без резьбы и испытал, что он сделал действительно блокировать поток? Возможно, вы слишком усложняете это. Тем не менее, некоторые доступные варианты:

  1. Surround потенциально длительный звонок с Thread.BeginThreadAffinity() и Thread.EndThreadAfinity(), как рекомендовано в этом comment.

  2. ли многопоточность в том, что сводится к «старомодному» способу, создавая новый Thread, который обрабатывает затянувшийся вызов, и ждать его завершения в цикле, который вызывает thread.sleep(x);:

    Thread _RunYouLongTime = new Thread(delegate); 
    _RunYouLongTime.Start(); 
    while (_RunYouLongTime.IsAlive) 
    { 
        System.Threading.Thread.Sleep(100); 
    } 
    
  3. Если долговременный вызов является HttpRequest/веб-сервисом, увеличьте свойство ServicePointManager.DefaultConnectionLimit. Это, вероятно, должно быть сделано независимо от того, как, или даже если вы выполняете потоки!

+0

Спасибо за этот ответ, я пробую его сейчас. –

+1

@Edwin Пожалуйста, смотрите мое обновление. Я добавил пример кода в случае, если было непонятно, что я имел в виду под «старомодным способом» ;-) –

+0

@Edwin Вы когда-нибудь получали эту работу? –

Смежные вопросы