<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>Question Re: Start a thread from CLR when called from SQL Anywhere in Technology Q&amp;A</title>
    <link>https://community.sap.com/t5/technology-q-a/start-a-thread-from-clr-when-called-from-sql-anywhere/qaa-p/13821828#M4852671</link>
    <description>&lt;P&gt;I don't have the answer, but like to hint to a different approach:&lt;/P&gt;
&lt;P&gt;You may trigger an event (i.e. call TRIGGER EVENT myEvent) from the trigger, and let that event (as it will run in a separate connection) call any asynchronous CLR call or whatever you like.&lt;/P&gt;
&lt;P&gt;At least that should de-couple the underlying DML statement from the CLR call, which might otherwise easily lead to errors and might rollback the current transaction....&lt;/P&gt;</description>
    <pubDate>Wed, 07 Mar 2012 09:20:36 GMT</pubDate>
    <dc:creator>VolkerBarth</dc:creator>
    <dc:date>2012-03-07T09:20:36Z</dc:date>
    <item>
      <title>Start a thread from CLR when called from SQL Anywhere</title>
      <link>https://community.sap.com/t5/technology-q-a/start-a-thread-from-clr-when-called-from-sql-anywhere/qaq-p/13821827</link>
      <description>&lt;P&gt;I am trying to trigger a url from a trigger in SQL Anywhere and not wait for the response.&lt;/P&gt;
&lt;P&gt;In SQL Anywhere i have made the following function:&lt;/P&gt;
&lt;DIV class="codehilite"&gt;&lt;PRE&gt;&lt;SPAN class="n"&gt;CREATE&lt;/SPAN&gt; &lt;SPAN class="n"&gt;FUNCTION&lt;/SPAN&gt; &lt;SPAN class="s"&gt;"DBA"&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="s"&gt;"sendCallback"&lt;/SPAN&gt;&lt;SPAN class="p"&gt;(&lt;/SPAN&gt; &lt;SPAN class="n"&gt;in&lt;/SPAN&gt; &lt;SPAN class="nv"&gt;@serverip&lt;/SPAN&gt; &lt;SPAN class="n"&gt;text&lt;/SPAN&gt;&lt;SPAN class="p"&gt;,&lt;/SPAN&gt;&lt;SPAN class="n"&gt;in&lt;/SPAN&gt; &lt;SPAN class="nv"&gt;@url&lt;/SPAN&gt; &lt;SPAN class="n"&gt;text&lt;/SPAN&gt; &lt;SPAN class="p"&gt;)&lt;/SPAN&gt; 
&lt;SPAN class="n"&gt;returns&lt;/SPAN&gt; &lt;SPAN class="n"&gt;char&lt;/SPAN&gt;&lt;SPAN class="p"&gt;(&lt;/SPAN&gt;&lt;SPAN class="mi"&gt;255&lt;/SPAN&gt;&lt;SPAN class="p"&gt;)&lt;/SPAN&gt;
&lt;SPAN class="ow"&gt;not&lt;/SPAN&gt; &lt;SPAN class="n"&gt;deterministic&lt;/SPAN&gt;
&lt;SPAN class="n"&gt;external&lt;/SPAN&gt; &lt;SPAN class="n"&gt;name&lt;/SPAN&gt; &lt;SPAN class="s"&gt;'Callback.dll::Namspace.Callback.OpenUrlAsync(string, string) string'&lt;/SPAN&gt; &lt;SPAN class="n"&gt;language&lt;/SPAN&gt; &lt;SPAN class="n"&gt;CLR&lt;/SPAN&gt;
&lt;/PRE&gt;&lt;/DIV&gt;


&lt;P&gt;And in C# i have made the folowing program:&lt;/P&gt;
&lt;DIV class="codehilite"&gt;&lt;PRE&gt;&lt;SPAN class="n"&gt;using&lt;/SPAN&gt; &lt;SPAN class="n"&gt;System&lt;/SPAN&gt;&lt;SPAN class="p"&gt;;&lt;/SPAN&gt;
&lt;SPAN class="n"&gt;using&lt;/SPAN&gt; &lt;SPAN class="n"&gt;System&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;Collections&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;Generic&lt;/SPAN&gt;&lt;SPAN class="p"&gt;;&lt;/SPAN&gt;
&lt;SPAN class="n"&gt;using&lt;/SPAN&gt; &lt;SPAN class="n"&gt;System&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;Linq&lt;/SPAN&gt;&lt;SPAN class="p"&gt;;&lt;/SPAN&gt;
&lt;SPAN class="n"&gt;using&lt;/SPAN&gt; &lt;SPAN class="n"&gt;System&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;Text&lt;/SPAN&gt;&lt;SPAN class="p"&gt;;&lt;/SPAN&gt;
&lt;SPAN class="n"&gt;using&lt;/SPAN&gt; &lt;SPAN class="n"&gt;System&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;Threading&lt;/SPAN&gt;&lt;SPAN class="p"&gt;;&lt;/SPAN&gt;
&lt;SPAN class="n"&gt;using&lt;/SPAN&gt; &lt;SPAN class="n"&gt;System&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;Net&lt;/SPAN&gt;&lt;SPAN class="p"&gt;;&lt;/SPAN&gt;
&lt;SPAN class="n"&gt;using&lt;/SPAN&gt; &lt;SPAN class="n"&gt;System&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;ComponentModel&lt;/SPAN&gt;&lt;SPAN class="p"&gt;;&lt;/SPAN&gt;

&lt;SPAN class="n"&gt;namespace&lt;/SPAN&gt; &lt;SPAN class="n"&gt;Namspace&lt;/SPAN&gt;
&lt;SPAN class="p"&gt;{&lt;/SPAN&gt;
    &lt;SPAN class="n"&gt;public&lt;/SPAN&gt; &lt;SPAN class="n"&gt;static&lt;/SPAN&gt; &lt;SPAN class="n"&gt;class&lt;/SPAN&gt; &lt;SPAN class="n"&gt;Callback&lt;/SPAN&gt;
    &lt;SPAN class="p"&gt;{&lt;/SPAN&gt;

        &lt;SPAN class="n"&gt;public&lt;/SPAN&gt; &lt;SPAN class="n"&gt;static&lt;/SPAN&gt; &lt;SPAN class="n"&gt;string&lt;/SPAN&gt; &lt;SPAN class="n"&gt;OpenUrlAsync&lt;/SPAN&gt;&lt;SPAN class="p"&gt;(&lt;/SPAN&gt;&lt;SPAN class="n"&gt;string&lt;/SPAN&gt; &lt;SPAN class="n"&gt;server&lt;/SPAN&gt;&lt;SPAN class="p"&gt;,&lt;/SPAN&gt; &lt;SPAN class="n"&gt;string&lt;/SPAN&gt; &lt;SPAN class="n"&gt;url&lt;/SPAN&gt;&lt;SPAN class="p"&gt;)&lt;/SPAN&gt;
        &lt;SPAN class="p"&gt;{&lt;/SPAN&gt;
            &lt;SPAN class="n"&gt;try&lt;/SPAN&gt;
            &lt;SPAN class="p"&gt;{&lt;/SPAN&gt;
                &lt;SPAN class="n"&gt;Thread&lt;/SPAN&gt; &lt;SPAN class="n"&gt;t1&lt;/SPAN&gt; &lt;SPAN class="o"&gt;=&lt;/SPAN&gt; &lt;SPAN class="k"&gt;new&lt;/SPAN&gt; &lt;SPAN class="n"&gt;System&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;Threading&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;Thread&lt;/SPAN&gt;
                  &lt;SPAN class="p"&gt;(()&lt;/SPAN&gt; &lt;SPAN class="o"&gt;=&amp;gt;&lt;/SPAN&gt;
                  &lt;SPAN class="p"&gt;{&lt;/SPAN&gt;
                      &lt;SPAN class="n"&gt;using&lt;/SPAN&gt; &lt;SPAN class="p"&gt;(&lt;/SPAN&gt;&lt;SPAN class="n"&gt;WebClient&lt;/SPAN&gt; &lt;SPAN class="n"&gt;wc&lt;/SPAN&gt; &lt;SPAN class="o"&gt;=&lt;/SPAN&gt; &lt;SPAN class="k"&gt;new&lt;/SPAN&gt; &lt;SPAN class="n"&gt;WebClient&lt;/SPAN&gt;&lt;SPAN class="p"&gt;())&lt;/SPAN&gt;
                      &lt;SPAN class="p"&gt;{&lt;/SPAN&gt;
                          &lt;SPAN class="n"&gt;try&lt;/SPAN&gt;
                          &lt;SPAN class="p"&gt;{&lt;/SPAN&gt;
                              &lt;SPAN class="n"&gt;string&lt;/SPAN&gt; &lt;SPAN class="n"&gt;result&lt;/SPAN&gt; &lt;SPAN class="o"&gt;=&lt;/SPAN&gt; &lt;SPAN class="n"&gt;wc&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;DownloadString&lt;/SPAN&gt;&lt;SPAN class="p"&gt;(&lt;/SPAN&gt;&lt;SPAN class="n"&gt;server&lt;/SPAN&gt; &lt;SPAN class="o"&gt;+&lt;/SPAN&gt; &lt;SPAN class="n"&gt;url&lt;/SPAN&gt;&lt;SPAN class="p"&gt;);&lt;/SPAN&gt;
                          &lt;SPAN class="p"&gt;}&lt;/SPAN&gt;
                          &lt;SPAN class="n"&gt;catch&lt;/SPAN&gt; &lt;SPAN class="p"&gt;(&lt;/SPAN&gt;&lt;SPAN class="n"&gt;Exception&lt;/SPAN&gt; &lt;SPAN class="n"&gt;ee&lt;/SPAN&gt;&lt;SPAN class="p"&gt;)&lt;/SPAN&gt;
                          &lt;SPAN class="p"&gt;{&lt;/SPAN&gt;
                              &lt;SPAN class="n"&gt;Console&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;Error&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;WriteLine&lt;/SPAN&gt;&lt;SPAN class="p"&gt;(&lt;/SPAN&gt;&lt;SPAN class="n"&gt;ee&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;Message&lt;/SPAN&gt;&lt;SPAN class="p"&gt;);&lt;/SPAN&gt;
                          &lt;SPAN class="p"&gt;}&lt;/SPAN&gt;
                      &lt;SPAN class="p"&gt;}&lt;/SPAN&gt;
                  &lt;SPAN class="p"&gt;});&lt;/SPAN&gt;
                &lt;SPAN class="n"&gt;t1&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;Start&lt;/SPAN&gt;&lt;SPAN class="p"&gt;();&lt;/SPAN&gt;

            &lt;SPAN class="p"&gt;}&lt;/SPAN&gt;
            &lt;SPAN class="n"&gt;catch&lt;/SPAN&gt; &lt;SPAN class="p"&gt;(&lt;/SPAN&gt;&lt;SPAN class="n"&gt;Exception&lt;/SPAN&gt; &lt;SPAN class="n"&gt;e&lt;/SPAN&gt;&lt;SPAN class="p"&gt;)&lt;/SPAN&gt;
            &lt;SPAN class="p"&gt;{&lt;/SPAN&gt;
                &lt;SPAN class="n"&gt;Console&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;Error&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;WriteLine&lt;/SPAN&gt;&lt;SPAN class="p"&gt;(&lt;/SPAN&gt;&lt;SPAN class="n"&gt;e&lt;/SPAN&gt;&lt;SPAN class="o"&gt;.&lt;/SPAN&gt;&lt;SPAN class="n"&gt;Message&lt;/SPAN&gt;&lt;SPAN class="p"&gt;);&lt;/SPAN&gt;
            &lt;SPAN class="p"&gt;}&lt;/SPAN&gt;

            &lt;SPAN class="k"&gt;return&lt;/SPAN&gt; &lt;SPAN class="s"&gt;"done"&lt;/SPAN&gt;&lt;SPAN class="p"&gt;;&lt;/SPAN&gt;
        &lt;SPAN class="p"&gt;}&lt;/SPAN&gt;

    &lt;SPAN class="p"&gt;}&lt;/SPAN&gt;
&lt;SPAN class="p"&gt;}&lt;/SPAN&gt;
&lt;/PRE&gt;&lt;/DIV&gt;


&lt;P&gt;When i call this from ISQL it works perfectly, but when it is called from the trigger it loks like the tread gets aborted before it can make the call.&lt;/P&gt;
&lt;P&gt;If i add t1.Join() after it is started i get the desired effect, but then it uses to much time to be called from a trigger.&lt;/P&gt;
&lt;P&gt;Is it correct that the CLR gets "teared down" when the connection calling it is finished?
How can i make sure the thread finishes?&lt;/P&gt;</description>
      <pubDate>Wed, 07 Mar 2012 09:04:30 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/start-a-thread-from-clr-when-called-from-sql-anywhere/qaq-p/13821827</guid>
      <dc:creator>Former Member</dc:creator>
      <dc:date>2012-03-07T09:04:30Z</dc:date>
    </item>
    <item>
      <title>Re: Start a thread from CLR when called from SQL Anywhere</title>
      <link>https://community.sap.com/t5/technology-q-a/start-a-thread-from-clr-when-called-from-sql-anywhere/qaa-p/13821828#M4852671</link>
      <description>&lt;P&gt;I don't have the answer, but like to hint to a different approach:&lt;/P&gt;
&lt;P&gt;You may trigger an event (i.e. call TRIGGER EVENT myEvent) from the trigger, and let that event (as it will run in a separate connection) call any asynchronous CLR call or whatever you like.&lt;/P&gt;
&lt;P&gt;At least that should de-couple the underlying DML statement from the CLR call, which might otherwise easily lead to errors and might rollback the current transaction....&lt;/P&gt;</description>
      <pubDate>Wed, 07 Mar 2012 09:20:36 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/start-a-thread-from-clr-when-called-from-sql-anywhere/qaa-p/13821828#M4852671</guid>
      <dc:creator>VolkerBarth</dc:creator>
      <dc:date>2012-03-07T09:20:36Z</dc:date>
    </item>
    <item>
      <title>Re: Start a thread from CLR when called from SQL Anywhere</title>
      <link>https://community.sap.com/t5/technology-q-a/start-a-thread-from-clr-when-called-from-sql-anywhere/qaa-p/13821829#M4852672</link>
      <description>&lt;P&gt;Of cource, my other approach was to have an event trigger every 1 sec and call from that one. I completely forgot taht i can trigger a event from code and make stuff "async" that way.&lt;/P&gt;</description>
      <pubDate>Wed, 07 Mar 2012 09:21:49 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/start-a-thread-from-clr-when-called-from-sql-anywhere/qaa-p/13821829#M4852672</guid>
      <dc:creator>Former Member</dc:creator>
      <dc:date>2012-03-07T09:21:49Z</dc:date>
    </item>
    <item>
      <title>Re: Start a thread from CLR when called from SQL Anywhere</title>
      <link>https://community.sap.com/t5/technology-q-a/start-a-thread-from-clr-when-called-from-sql-anywhere/qaa-p/13821830#M4852673</link>
      <description>&lt;P&gt;I tried using TRIGGER EVENT and that works perfectly until i get a lot of inserts. Then i get the folowing error in serverlog:&lt;/P&gt;
&lt;P&gt;Handler for event 'MeldFraOmNyeTider' caused SQLSTATE '40W06'
All threads are blocked&lt;/P&gt;</description>
      <pubDate>Thu, 08 Mar 2012 04:09:16 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/start-a-thread-from-clr-when-called-from-sql-anywhere/qaa-p/13821830#M4852673</guid>
      <dc:creator>Former Member</dc:creator>
      <dc:date>2012-03-08T04:09:16Z</dc:date>
    </item>
    <item>
      <title>Re: Start a thread from CLR when called from SQL Anywhere</title>
      <link>https://community.sap.com/t5/technology-q-a/start-a-thread-from-clr-when-called-from-sql-anywhere/qaa-p/13821831#M4852674</link>
      <description>&lt;P&gt;OK, each event will run own its own connection and will try to occupy a worker thread from the pool - this will be queueed, but obviously there's too much "activity"/"demand" in the end.&lt;/P&gt;
&lt;P&gt;Are you doing lots of single INSERTs (each inserting one row), or are these a few INSERT...SELECT statements but inserting many rows each?&lt;/P&gt;
&lt;P&gt;In the latter case: Are you using row-level or statement-level triggers - a statement-level trigger help to reduce the number of events that are triggered.&lt;/P&gt;
&lt;P&gt;As I don't know the actual task you are trying to achieve: A further approach would be to balance between a "push" and "poll" model, e.g. instead of triggering the event directly in the DML trigger, insert into a temp table, and then use some logic to trigger the event from that temp table once a certain limit/counter is hit...&lt;/P&gt;</description>
      <pubDate>Thu, 08 Mar 2012 04:59:08 GMT</pubDate>
      <guid>https://community.sap.com/t5/technology-q-a/start-a-thread-from-clr-when-called-from-sql-anywhere/qaa-p/13821831#M4852674</guid>
      <dc:creator>VolkerBarth</dc:creator>
      <dc:date>2012-03-08T04:59:08Z</dc:date>
    </item>
  </channel>
</rss>

