title: Can I avoid duplicate code in similar methods for synchronous and async lambdas?
body: <p>I've got a helper method that takes a lambda to execute within a try/catch/finally block, e.g.</p>
  <pre><code>public void ProcessSpreadsheet(string filename, Action&lt;object[,]&gt; process) {
      try {
          // Open MS Excel workbook
          // Open sheet &amp; extract data into valueArray
          // ... more boiler plate ...
  
          process(valueArray);
      }
      catch (FooException e) {
          LogFoo(e.Message);
          throw;
      }
      catch (BarException e) {
          LogBar(e.Message);
          throw;
      }
      finally {
          // Close workbook, release resources, etc..
      }
  }
  </code></pre>
  <p>I would now like to create an async version that accepts an async lambda.</p>
  <p>(Note, I've read and agree with Stephen Toub's <a href="https://devblogs.microsoft.com/pfxteam/should-i-expose-asynchronous-wrappers-for-synchronous-methods/" rel="nofollow noreferrer">post</a><a href="https://devblogs.microsoft.com/pfxteam/should-i-expose-synchronous-wrappers-for-asynchronous-methods/" rel="nofollow noreferrer">s</a> on <em>async over sync</em>, but that doesn't apply here as the crux of the method, where asynchrony is or isn't beneficial, is supplied by the consumer via a lambda.)</p>
  <p>I can copy and paste the above, mark it as <code>async</code>, change the return type to <code>Task</code>, add &quot;Async&quot; to it's name, change the type of the <code>process</code> paramter to <code>Func&lt;object[,],Task&gt;</code> and change</p>
  <pre><code>process(valueArray);
  </code></pre>
  <p>to</p>
  <pre><code>await process(valueArray);
  </code></pre>
  <p>and everything works fine. But I'd like to avoid repeating all the code in the try/catch/finally. Is there a clean way to achieve this without repeated code?</p>
  <p>So far the best solution I've got is:</p>
  <pre><code>public async Task ProcessSpreadsheetAsync(string filename, Func&lt;object[,],Task&gt; process) {
      var asyncTaskComplete = new ManualResetEvent(false);
      ProcessSpreadsheet(filename, async valueArray =&gt; {
          await process(valueArray);
          asyncTaskComplete.Set();
      });
      await Task.Run(() =&gt; asyncTaskComplete.WaitOne());
  }
  </code></pre>
  <p>but it's messy and the exceptions aren't handled. I'm wondering if there's another way?</p>