【问题标题】:SQL CLR awaitable not getting executedSQL CLR 等待未执行
【发布时间】:2016-09-27 23:17:44
【问题描述】:

据我了解,可等待对象在从等待返回时完成了执行代码的剩余部分。我试图让它在 sql clr 中工作,但这不起作用,因为等待的进程和它下面的代码都没有被执行。 在调试方法中,控件在执行完等待行后才返回。

我怎样才能完成这项工作,因为要求是在不阻塞主线程的情况下执行 clr,以便其他工作可以在 db 中继续进行。 我真的需要它来工作,并且已经使用了 2 天了。

注意 如果方法是同步的,这很有效。 并且存储的proc assemble在sql server中注册为不安全的。 我正在使用 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):


        }

    }
}

【问题讨论】:

  • 你不应该使用async void,除非你正在编写一个事件处理程序和async Taskis not supported by sqlclr
  • @ScottChamberlain 该方法默认无效,在项目中添加新的 sql c# clr 时可以看到。我只用 async 装饰它,因为这是在方法主体中使用 await 的要求,你是说我可以更改方法返回类型吗?我还有哪些其他选项可以将异步任务线程化?
  • 对于SqlProcedure,只有两个有效的返回类型应该是:void 和SqlInt32。 SqlInt32 将是返回值(即RETURN 5;),可以使用以下方法捕获:DECLARE @ReturnVal INT; EXEC @ReturnVal = dbo.SomeProc;。
  • 除了在 SQL CLR 中使用 async-await 之外,您正在使用 Task&lt;T&gt; 构造函数并且从不启动任务。我怀疑,一旦你启动它,你就会得到一个运行时错误。

标签: c# sql-server multithreading async-await sqlclr


【解决方案1】:

要求是在不阻塞主线程的情况下执行 clr

您是否尝试过不使用线程并经历过它确实阻塞了线程?您可能过于复杂了。不过,一些可用的选项是:

  1. 按照comment 中的建议,用Thread.BeginThreadAffinity() 和Thread.EndThreadAfinity() 包围可能长时间运行的呼叫。

  2. 通过创建一个处理长时间运行的调用的新Thread 以相当于“老式”的方式执行多线程,并在调用thread.sleep(x); 的循环中等待它完成:

    Thread _RunYouLongTime = new Thread(delegate);
    _RunYouLongTime.Start();
    while (_RunYouLongTime.IsAlive)
    {
      System.Threading.Thread.Sleep(100);
    }
    
  3. 如果长时间运行的调用是 HttpRequest / Web 服务,则增加 ServicePointManager.DefaultConnectionLimit 属性。 无论您如何进行线程处理,或者即使您进行线程处理,都应该这样做!

【讨论】:

  • @Edwin 请查看我的更新。我添加了示例代码,以防我不清楚“老式方式”的意思;-)
猜你喜欢
  • 1970-01-01
  • 2023-03-04
  • 2012-05-03
  • 1970-01-01
  • 1970-01-01
  • 2020-08-16
  • 2020-10-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多