<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>UI Responsiveness &#8211; Xojo Programming Blog</title>
	<atom:link href="https://blog.xojo.com/tag/ui-responsiveness/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.xojo.com</link>
	<description>Blog about the Xojo programming language and IDE</description>
	<lastBuildDate>Mon, 02 Feb 2026 21:25:31 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>Optimizing Xojo Code, Part 4: Timer.CallLater</title>
		<link>https://blog.xojo.com/2026/02/02/optimizing-xojo-code-part-4-timer-calllater/</link>
		
		<dc:creator><![CDATA[Gabriel Ludosanu]]></dc:creator>
		<pubDate>Mon, 02 Feb 2026 21:25:28 +0000</pubDate>
				<category><![CDATA[Fun]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[CallLater]]></category>
		<category><![CDATA[CancelCallLater]]></category>
		<category><![CDATA[Developer Challenge]]></category>
		<category><![CDATA[Timers]]></category>
		<category><![CDATA[UI Responsiveness]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=15786</guid>

					<description><![CDATA[In&#160;Part 1&#160;of this series, we looked at a common but discouraged approach using a tight loop with&#160;DoEvents&#160;to keep the UI from freezing. In&#160;Part 2, we&#8230;]]></description>
										<content:encoded><![CDATA[
<p>In&nbsp;<a href="https://blog.xojo.com/2025/11/20/optimizing-xojo-code-part-1-getting-started/">Part 1</a>&nbsp;of this series, we looked at a common but discouraged approach using a tight loop with&nbsp;<code>DoEvents</code>&nbsp;to keep the UI from freezing. In&nbsp;<a href="https://blog.xojo.com/2025/11/25/optimizing-xojo-code-part-2-using-a-timer-to-keep-the-ui-responsive/">Part 2</a>, we explored a better alternative by replacing that loop with a Timer control dragged onto a Window. In&nbsp;<a href="https://blog.xojo.com/2026/01/14/optimizing-xojo-code-part-3-programmatic-timers-and-addhandler/">Part 3</a>, we advanced to creating Timers programmatically with&nbsp;<code>AddHandler</code>&nbsp;for use in classes and modules.</p>



<p>Now, for even simpler one-off or chained delayed tasks, Xojo offers&nbsp;<code>Timer.CallLater</code>: no Timer instance required.</p>



<h2 class="wp-block-heading" id="the-strategy-timercalllater">The Strategy: Timer.CallLater</h2>



<p><code>Timer.CallLater(milliseconds, AddressOf MethodName, arg As Variant)</code>&nbsp;schedules your method to run after the specified delay on the main UI thread. Pass data via the Variant parameter. To chain calls (like our countdown), re-call it from within the method. Use&nbsp;<code>Timer.CancelCallLater(AddressOf MethodName)</code>&nbsp;to abort pending calls.</p>



<p>For full details, see the&nbsp;<a href="https://documentation.xojo.com/api/language/timer.html" target="_blank" rel="noreferrer noopener">Timer documentation</a>.</p>



<h2 class="wp-block-heading" id="looking-at-the-code">Looking at the Code</h2>



<p>Prerequisites: Add a <code>StatusLabel</code> (DesktopLabel control) and a constant <code>kCountTo As Integer = 20000</code>.</p>



<p>Let&#8217;s look at how we implement this.</p>



<h3 class="wp-block-heading" id="the-setup-button-pressed">The Setup (Button Pressed)</h3>



<p>Place the following code in the&nbsp;<code>Pressed</code>&nbsp;event handler of a button control:</p>



<pre class="wp-block-code"><code>Sub Pressed()
  Timer.CancelCallLater(AddressOf UpdateProgress)
  
  StatusLabel.Text = "0"
  
  Timer.CallLater(100, AddressOf UpdateProgress, 100)
End Sub</code></pre>



<h3 class="wp-block-heading" id="the-handler-recursive-chain">The Handler (Recursive Chain)</h3>



<p>Create the following method that handles the recursive chain of delayed updates:</p>



<pre class="wp-block-code"><code>Sub UpdateProgress(elapsedMs As Variant)
  Var elapsed As Integer = elapsedMs.IntegerValue
  
  If elapsed &gt;= kCountTo Then

    StatusLabel.Text = "done"

  Else

    StatusLabel.Text = elapsed.ToString
    Timer.CallLater(100, AddressOf UpdateProgress, elapsed + 100)

  End If
End Sub</code></pre>



<p><strong>Crucial Note:</strong>&nbsp;The handler method must accept a&nbsp;<code>Variant</code>&nbsp;parameter to receive the argument passed to&nbsp;<code>CallLater</code>. Always use type-safe extraction like&nbsp;<code>.IntegerValue</code>.</p>



<h2 class="wp-block-heading" id="how-it-works">How It Works</h2>



<ol class="wp-block-list">
<li>Initial Schedule: The button cancels any pending calls and schedules the first <code>UpdateProgress</code> after 100ms, passing <code>100</code> as the elapsed time (just in case we like pressing a button multiple times quickly).</li>



<li>Recursion: Each call updates the UI and, if not finished, schedules the next one 100ms in the future with incremented elapsed time.</li>



<li>Automatic Management: No Timer properties or handlers to manage; Xojo handles scheduling and cleanup.</li>



<li>Cancellation: Ensures only one chain runs at a time.</li>
</ol>



<h2 class="wp-block-heading" id="wrapping-up">Wrapping Up</h2>



<p><code>Timer.CallLater</code>&nbsp;shines for delayed UI updates or chained tasks without the overhead of Timer objects. It&#8217;s concise, safe, and powerful for responsive apps.</p>



<p>In Part 5, we&#8217;ll tackle true background processing with&nbsp;<code>Threads</code>&nbsp;and&nbsp;<code>UserInterfaceUpdate</code>.</p>



<p>Until then, happy coding!</p>



<p><em>Gabriel is a digital marketing enthusiast who loves coding with Xojo to create cool software tools for any platform. He is always eager to learn and share new ideas!</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p><strong>Optimizing Code Series:</strong></p>



<ul class="wp-block-list">
<li><a href="https://blog.xojo.com/2025/11/20/optimizing-xojo-code-part-1-getting-started/" target="_blank" rel="noreferrer noopener">Optimizing Xojo Code, Part 1: Getting Started</a></li>



<li><a href="https://blog.xojo.com/2025/11/25/optimizing-xojo-code-part-2-using-a-timer-to-keep-the-ui-responsive/" target="_blank" rel="noreferrer noopener">Optimizing Xojo Code, Part 2: Using a Timer to Keep the UI Responsive</a></li>



<li><a href="https://blog.xojo.com/2026/01/14/optimizing-xojo-code-part-3-programmatic-timers-and-addhandler/" target="_blank" rel="noreferrer noopener">Optimizing Xojo Code, Part 3: Programmatic Timers and AddHandler</a></li>



<li><a href="https://blog.xojo.com/2026/02/02/optimizing-xojo-code-part-4-timer-calllater/" target="_blank" rel="noreferrer noopener">Optimizing Xojo Code, Part 4: Timer.CallLater</a></li>



<li><a href="https://blog.xojo.com/2026/03/02/optimizing-xojo-code-part-5-threads-and-userinterfaceupdate/" target="_blank" rel="noreferrer noopener">Optimizing Xojo Code, Part 5: Threads and UserInterfaceUpdate</a></li>
</ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Optimizing Xojo Code, Part 3: Programmatic Timers and AddHandler</title>
		<link>https://blog.xojo.com/2026/01/14/optimizing-xojo-code-part-3-programmatic-timers-and-addhandler/</link>
		
		<dc:creator><![CDATA[Gabriel Ludosanu]]></dc:creator>
		<pubDate>Wed, 14 Jan 2026 16:27:11 +0000</pubDate>
				<category><![CDATA[Fun]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[AddHandler]]></category>
		<category><![CDATA[Code Optimization]]></category>
		<category><![CDATA[Developer Challenge]]></category>
		<category><![CDATA[Timers]]></category>
		<category><![CDATA[UI Responsiveness]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=15768</guid>

					<description><![CDATA[In&#160;Part 1&#160;of this Optimizing Xojo Code series, we looked at a working but discouraged approach using a tight loop with&#160;DoEvents&#160;to keep the UI from freezing.&#8230;]]></description>
										<content:encoded><![CDATA[
<p>In&nbsp;<a href="https://blog.xojo.com/2025/11/20/optimizing-xojo-code-part-1-getting-started/">Part 1</a>&nbsp;of this Optimizing Xojo Code series, we looked at a working but discouraged approach using a tight loop with&nbsp;<code>DoEvents</code>&nbsp;to keep the UI from freezing. In&nbsp;<a href="https://blog.xojo.com/2025/11/25/optimizing-xojo-code-part-2-using-a-timer-to-keep-the-ui-responsive/">Part 2</a>, we explored a better alternative by replacing that loop with a Timer control dragged onto a DesktopWindow. This is a simple and effective solution that takes advantage of Xojo’s object-oriented nature.</p>



<p>But what if you need a timer inside a Class or a Module where you can&#8217;t drop a visual control?</p>



<h2 class="wp-block-heading" id="the-strategy-addhandler">The Strategy: AddHandler</h2>



<p>When you use a Timer control from the library, you double-click it to add an&nbsp;<code>Action</code>&nbsp;event. When we create a Timer in code, we don&#8217;t have a &#8220;code editor&#8221; for it in the same way. Instead, we use the&nbsp;<code>AddHandler</code>&nbsp;command to tell Xojo: &#8220;When this timer fires its Action event, run this specific method instead.&#8221;</p>



<h2 class="wp-block-heading" id="looking-at-the-code">Looking at the Code</h2>



<p>Let&#8217;s look at how we implement this. In our example project, we have a button that initializes our timer and a separate method to handle the &#8220;ticks.&#8221;</p>



<h3 class="wp-block-heading" id="the-setup-opening-the-gate">The Setup</h3>



<p>First, we define a property on our window (or class) to hold our timer:&nbsp;<code>mWaitTimer As Timer</code></p>



<p>Then, in the&nbsp;<strong>Pressed</strong>&nbsp;event of our button, we instantiate it:</p>



<pre class="wp-block-code"><code>Sub Pressed() Handles Pressed
  ' 1. Cleanup
  If mWaitTimer &lt;&gt; Nil Then
    mWaitTimer.RunMode = Timer.RunModes.Off
    mWaitTimer = Nil
  End If
  
  ' 2. Initialization
  mElapsedMs = 0
  StatusLabel.Text = "0"
  
  ' 3. Create the dynamic timer
  mWaitTimer = New Timer
  mWaitTimer.Period = 100 ' 100 ms tick
  mWaitTimer.RunMode = Timer.RunModes.Multiple
  
  ' 4. The Magic: Link the Action event to our WaitTick method
  AddHandler mWaitTimer.Action, AddressOf WaitTick
End Sub</code></pre>



<h3 class="wp-block-heading" id="the-handler-doing-the-work">The Handler (Doing the Work)</h3>



<p>Now, let&#8217;s create the method named&nbsp;<code>WaitTick</code>.&nbsp;<strong>Crucial Note:</strong>&nbsp;When using&nbsp;<code>AddHandler</code>&nbsp;for a Timer, the first parameter of your receiving method must be of the type&nbsp;<code>Timer</code>&nbsp;so it knows which object triggered it.</p>



<pre class="wp-block-code"><code>Sub WaitTick(t As Timer)
  mElapsedMs = mElapsedMs + t.Period
  
  If mElapsedMs &gt;= kCountTo Then
    ' Achievement unlocked! Stop the timer and clean up
    t.RunMode = Timer.RunModes.Off
    StatusLabel.Text = "done"
    
    ' It's good practice to remove the handler when done
    RemoveHandler t.Action, AddressOf WaitTick
  Else
    StatusLabel.Text = mElapsedMs.ToString
  End If
End Sub</code></pre>



<h2 class="wp-block-heading" id="how-it-works">How It Works</h2>



<ol class="wp-block-list">
<li><strong>New Timer:</strong>&nbsp;We create a new instance of the Timer class in memory.</li>



<li><strong>AddHandler:</strong>&nbsp;This command connects the&nbsp;<code>Action</code>&nbsp;event of our new timer to the&nbsp;<code>WaitTick</code>&nbsp;method. The&nbsp;<code>AddressOf</code>&nbsp;operator tells Xojo the memory location of the code we want to run.</li>



<li><strong>Passing the Object:</strong>&nbsp;Because&nbsp;<code>WaitTick</code>&nbsp;receives&nbsp;<code>t As Timer</code>&nbsp;as a parameter, you can actually use the same handler for multiple different timers and knows exactly which one is calling for attention.</li>
</ol>



<h2 class="wp-block-heading" id="wrapping-up">Wrapping Up</h2>



<p>By moving your Timers into code, you take a significant step toward writing more modular Xojo applications. You’ve moved the logic from &#8220;Global UI state&#8221; into &#8220;Managed Code execution.&#8221;</p>



<p>In the upcoming Part 4, we’ll look at a shortcut that makes one-off background tasks a breeze:&nbsp;<code>Timer.CallLater</code>.</p>



<p>Until then, happy coding and don&#8217;t forget to add your own solution in the <a href="https://forum.xojo.com/" data-type="link" data-id="https://forum.xojo.com/" target="_blank" rel="noreferrer noopener">Xojo Forum</a>!</p>



<p><em>Gabriel is a digital marketing enthusiast who loves coding with Xojo to create cool software tools for any platform. He is always eager to learn and share new ideas!</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p><strong>Optimizing Code Series:</strong></p>



<ul class="wp-block-list">
<li><a href="https://blog.xojo.com/2025/11/20/optimizing-xojo-code-part-1-getting-started/" target="_blank" rel="noreferrer noopener">Optimizing Xojo Code, Part 1: Getting Started</a></li>



<li><a href="https://blog.xojo.com/2025/11/25/optimizing-xojo-code-part-2-using-a-timer-to-keep-the-ui-responsive/" target="_blank" rel="noreferrer noopener">Optimizing Xojo Code, Part 2: Using a Timer to Keep the UI Responsive</a></li>



<li><a href="https://blog.xojo.com/2026/01/14/optimizing-xojo-code-part-3-programmatic-timers-and-addhandler/" target="_blank" rel="noreferrer noopener">Optimizing Xojo Code, Part 3: Programmatic Timers and AddHandler</a></li>



<li><a href="https://blog.xojo.com/2026/02/02/optimizing-xojo-code-part-4-timer-calllater/" target="_blank" rel="noreferrer noopener">Optimizing Xojo Code, Part 4: Timer.CallLater</a></li>



<li><a href="https://blog.xojo.com/2026/03/02/optimizing-xojo-code-part-5-threads-and-userinterfaceupdate/" target="_blank" rel="noreferrer noopener">Optimizing Xojo Code, Part 5: Threads and UserInterfaceUpdate</a></li>
</ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Optimizing Xojo Code, Part 2: Using a Timer to Keep the UI Responsive</title>
		<link>https://blog.xojo.com/2025/11/25/optimizing-xojo-code-part-2-using-a-timer-to-keep-the-ui-responsive/</link>
		
		<dc:creator><![CDATA[Gabriel Ludosanu]]></dc:creator>
		<pubDate>Tue, 25 Nov 2025 16:00:00 +0000</pubDate>
				<category><![CDATA[Fun]]></category>
		<category><![CDATA[Learning]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Code Optimization]]></category>
		<category><![CDATA[Developer Challenge]]></category>
		<category><![CDATA[Timers]]></category>
		<category><![CDATA[UI Responsiveness]]></category>
		<guid isPermaLink="false">https://blog.xojo.com/?p=15526</guid>

					<description><![CDATA[Welcome back! If you missed the first part in this series, check out Optimizing Xojo Code, Part 1: Getting Started, where we dissected the blocking&#8230;]]></description>
										<content:encoded><![CDATA[
<p>Welcome back! If you missed the first part in this series, check out <strong><a href="https://blog.xojo.com/2025/11/20/optimizing-xojo-code-part-1-getting-started/">Optimizing Xojo Code, Part 1: Getting Started</a></strong>, where we dissected the blocking <code>While</code> loop that counted up to <code>kCountTo</code>, updated a label, and kept the UI responsive only by calling <code>App.DoEvents</code>. That code works, but it spends most of its life running on the UI thread. In this tutorial we’ll rebuild that workflow step by step and end up with the first optimized solution: a timer-driven solution that keeps the interface responsive.</p>



<h3 class="wp-block-heading">Step 1: Let&#8217;s sketch the goal</h3>



<p>We will need a button that, when pressed, starts a simulated wait that updates a label every 100 ms until a fixed duration (<code>kCountTo</code>, which remains <code>20000</code> ms in our example) is reached. So, the timer will fire periodically and handle the counting there. The button simply resets state and starts the timer.</p>



<h3 class="wp-block-heading">Step 2: Prepare the UI components</h3>



<p>Create a <code>DesktopLabel</code> named <code>StatusLabel</code> to display progress.<br>Add a <code>DesktopButton</code> (caption it “Method 1”) whose <code>Pressed</code> event will kick off the timer.<br>Finally, place a <code>Timer</code> control onto the window, name it <code>mTimer</code>, set its <code>Period</code> to <code>100</code>, and set <code>RunMode</code> to <code>Multiple</code> (but leave it off until the button starts it).<br>Add an <code>Integer</code> property to the window such as <code>mMsWaited</code> to accumulate elapsed milliseconds, and keep <code>kCountTo</code> defined as <code>20000</code>.</p>



<h3 class="wp-block-heading">Step 3: Wire up the button</h3>



<p>The button handler becomes very simple. Reset the tracked milliseconds, show <code>"0"</code> in the label, ensure the timer runs at 100 ms ticks, and let it fire repeatedly:</p>



<pre class="wp-block-code"><code>Sub Pressed()
  // Reset the tracked elapsed ms and start the timer at 100 ms ticks.
  mMsWaited = 0
  StatusLabel.Text = "0"
  mTimer.Period = 100
  mTimer.RunMode = Timer.RunModes.Multiple
End Sub</code></pre>



<p>This code primes the state but does not block. The timer will perform the actual counting.</p>



<h3 class="wp-block-heading">Step 4: Let the timer take over</h3>



<p>Implement <code>mTimer.Action</code> to run on the UI thread. Each tick adds the timer’s period to <code>mMsWaited</code>, updates the label, and turns itself off once <code>kCountTo</code> has been reached:</p>



<pre class="wp-block-code"><code>Sub Action()
  mMsWaited = mMsWaited + Me.Period

  If mMsWaited &gt;= kCountTo Then
    Me.RunMode = Timer.RunModes.Off
    StatusLabel.Text = "done"
  Else
    StatusLabel.Text = mMsWaited.ToString
  End If
End Sub</code></pre>



<p>This keeps your UI responsive because the timer fires briefly and returns control back to the event loop instead of spinning inside a <code>While</code> loop.</p>



<h3 class="wp-block-heading">Step 5: Test the flow</h3>



<p>Run the app, click the button previously created and watch the label count up and stop at the target value. The timer approach lets other interface interactions remain responsive while still providing clear progress feedback.</p>



<h2 class="wp-block-heading">What makes this timer driven solution a solid first step?</h2>



<p>It shows how you can preserve the original behavior while giving the UI breathing room. It avoids <code>App.DoEvents</code>, reduces tight loops, and still delivers frequent updates. In the next article we’ll build on this idea and explore alternative approaches that continue to improve responsiveness and structure.</p>



<p><em>Gabriel is a digital marketing enthusiast who loves coding with Xojo to create cool software tools for any platform. He is always eager to learn and share new ideas!</em></p>



<ul class="wp-block-social-links has-normal-icon-size is-content-justification-center is-layout-flex wp-container-core-social-links-is-layout-16018d1d wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.facebook.com/goxojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li>

<li class="wp-social-link wp-social-link-x  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://x.com/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M13.982 10.622 20.54 3h-1.554l-5.693 6.618L8.745 3H3.5l6.876 10.007L3.5 21h1.554l6.012-6.989L15.868 21h5.245l-7.131-10.378Zm-2.128 2.474-.697-.997-5.543-7.93H8l4.474 6.4.697.996 5.815 8.318h-2.387l-4.745-6.787Z" /></svg><span class="wp-block-social-link-label screen-reader-text">X</span></a></li>

<li class="wp-social-link wp-social-link-linkedin  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.linkedin.com/company/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M19.7,3H4.3C3.582,3,3,3.582,3,4.3v15.4C3,20.418,3.582,21,4.3,21h15.4c0.718,0,1.3-0.582,1.3-1.3V4.3 C21,3.582,20.418,3,19.7,3z M8.339,18.338H5.667v-8.59h2.672V18.338z M7.004,8.574c-0.857,0-1.549-0.694-1.549-1.548 c0-0.855,0.691-1.548,1.549-1.548c0.854,0,1.547,0.694,1.547,1.548C8.551,7.881,7.858,8.574,7.004,8.574z M18.339,18.338h-2.669 v-4.177c0-0.996-0.017-2.278-1.387-2.278c-1.389,0-1.601,1.086-1.601,2.206v4.249h-2.667v-8.59h2.559v1.174h0.037 c0.356-0.675,1.227-1.387,2.526-1.387c2.703,0,3.203,1.779,3.203,4.092V18.338z"></path></svg><span class="wp-block-social-link-label screen-reader-text">LinkedIn</span></a></li>

<li class="wp-social-link wp-social-link-github  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://github.com/topics/xojo" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12,2C6.477,2,2,6.477,2,12c0,4.419,2.865,8.166,6.839,9.489c0.5,0.09,0.682-0.218,0.682-0.484 c0-0.236-0.009-0.866-0.014-1.699c-2.782,0.602-3.369-1.34-3.369-1.34c-0.455-1.157-1.11-1.465-1.11-1.465 c-0.909-0.62,0.069-0.608,0.069-0.608c1.004,0.071,1.532,1.03,1.532,1.03c0.891,1.529,2.341,1.089,2.91,0.833 c0.091-0.647,0.349-1.086,0.635-1.337c-2.22-0.251-4.555-1.111-4.555-4.943c0-1.091,0.39-1.984,1.03-2.682 C6.546,8.54,6.202,7.524,6.746,6.148c0,0,0.84-0.269,2.75,1.025C10.295,6.95,11.15,6.84,12,6.836 c0.85,0.004,1.705,0.114,2.504,0.336c1.909-1.294,2.748-1.025,2.748-1.025c0.546,1.376,0.202,2.394,0.1,2.646 c0.64,0.699,1.026,1.591,1.026,2.682c0,3.841-2.337,4.687-4.565,4.935c0.359,0.307,0.679,0.917,0.679,1.852 c0,1.335-0.012,2.415-0.012,2.741c0,0.269,0.18,0.579,0.688,0.481C19.138,20.161,22,16.416,22,12C22,6.477,17.523,2,12,2z"></path></svg><span class="wp-block-social-link-label screen-reader-text">GitHub</span></a></li>

<li class="wp-social-link wp-social-link-youtube  wp-block-social-link"><a rel="noopener nofollow" target="_blank" href="https://www.youtube.com/c/XojoInc" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul>



<p><strong>Optimizing Code Series:</strong></p>



<ul class="wp-block-list">
<li><a href="https://blog.xojo.com/2025/11/20/optimizing-xojo-code-part-1-getting-started/" target="_blank" rel="noreferrer noopener">Optimizing Xojo Code, Part 1: Getting Started</a></li>



<li><a href="https://blog.xojo.com/2025/11/25/optimizing-xojo-code-part-2-using-a-timer-to-keep-the-ui-responsive/" target="_blank" rel="noreferrer noopener">Optimizing Xojo Code, Part 2: Using a Timer to Keep the UI Responsive</a></li>



<li><a href="https://blog.xojo.com/2026/01/14/optimizing-xojo-code-part-3-programmatic-timers-and-addhandler/" target="_blank" rel="noreferrer noopener">Optimizing Xojo Code, Part 3: Programmatic Timers and AddHandler</a></li>



<li><a href="https://blog.xojo.com/2026/02/02/optimizing-xojo-code-part-4-timer-calllater/" target="_blank" rel="noreferrer noopener">Optimizing Xojo Code, Part 4: Timer.CallLater</a></li>



<li><a href="https://blog.xojo.com/2026/03/02/optimizing-xojo-code-part-5-threads-and-userinterfaceupdate/" target="_blank" rel="noreferrer noopener">Optimizing Xojo Code, Part 5: Threads and UserInterfaceUpdate</a></li>
</ul>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
