Why is the call ambiguous? 'Task.Run(Action)' and 'Task.Run(Func)'

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
20
down vote

favorite
1












Considering the following code:



public void CacheData()

Task.Run((Action)CacheExternalData);
Task.Run(() => CacheExternalData());

Task.Run(CacheExternalDataTask);

Task.Run(CacheExternalData);


public Task CacheExternalDataTask()

// Long running code
return Task.FromResult("Data");


public void CacheExternalData()

// Long running code



Why is Task.Run(CacheExternalData) ambiguous? And Task.Run(CacheExternalDataTask) is not?



When calling Task.Run with CacheExternalData I would have thought it was clear to the compiler that the method does not return a Task and it should resolve to an Action?







share|improve this question


























    up vote
    20
    down vote

    favorite
    1












    Considering the following code:



    public void CacheData()

    Task.Run((Action)CacheExternalData);
    Task.Run(() => CacheExternalData());

    Task.Run(CacheExternalDataTask);

    Task.Run(CacheExternalData);


    public Task CacheExternalDataTask()

    // Long running code
    return Task.FromResult("Data");


    public void CacheExternalData()

    // Long running code



    Why is Task.Run(CacheExternalData) ambiguous? And Task.Run(CacheExternalDataTask) is not?



    When calling Task.Run with CacheExternalData I would have thought it was clear to the compiler that the method does not return a Task and it should resolve to an Action?







    share|improve this question
























      up vote
      20
      down vote

      favorite
      1









      up vote
      20
      down vote

      favorite
      1






      1





      Considering the following code:



      public void CacheData()

      Task.Run((Action)CacheExternalData);
      Task.Run(() => CacheExternalData());

      Task.Run(CacheExternalDataTask);

      Task.Run(CacheExternalData);


      public Task CacheExternalDataTask()

      // Long running code
      return Task.FromResult("Data");


      public void CacheExternalData()

      // Long running code



      Why is Task.Run(CacheExternalData) ambiguous? And Task.Run(CacheExternalDataTask) is not?



      When calling Task.Run with CacheExternalData I would have thought it was clear to the compiler that the method does not return a Task and it should resolve to an Action?







      share|improve this question














      Considering the following code:



      public void CacheData()

      Task.Run((Action)CacheExternalData);
      Task.Run(() => CacheExternalData());

      Task.Run(CacheExternalDataTask);

      Task.Run(CacheExternalData);


      public Task CacheExternalDataTask()

      // Long running code
      return Task.FromResult("Data");


      public void CacheExternalData()

      // Long running code



      Why is Task.Run(CacheExternalData) ambiguous? And Task.Run(CacheExternalDataTask) is not?



      When calling Task.Run with CacheExternalData I would have thought it was clear to the compiler that the method does not return a Task and it should resolve to an Action?









      share|improve this question













      share|improve this question




      share|improve this question








      edited Aug 14 at 13:52









      Boann

      35.5k1184116




      35.5k1184116










      asked Aug 14 at 9:08









      Tom.Bowen89

      4,21421437




      4,21421437






















          1 Answer
          1






          active

          oldest

          votes

















          up vote
          24
          down vote



          accepted










          It should be clear, but the language specification never said that mismatched return types would have any effect during overload resolution. Because of that, there was no rule that said to prefer Action over Func<Task>. If Action would be picked, sure, it would work. If Func<Task> would be picked, then sure, you'd get an error. But to pick either, overload resolution has to succeed, and it isn't taking this into account.



          This is supposed to be fixed with new overload resolution in C# 7.3.






          share|improve this answer
















          • 8




            To confirm: yes, it is fixed in 7.3; adding <LangVer>7.3</LangVer> to a test project makes it resolve correctly
            – Marc Gravell♦
            Aug 14 at 9:18






          • 1




            It was a pretty obvious bug in the specification.
            – Joshua
            Aug 14 at 17:25










          Your Answer





          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "1"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );








           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f51837722%2fwhy-is-the-call-ambiguous-task-runaction-and-task-runfunctask%23new-answer', 'question_page');

          );

          Post as a guest






























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          24
          down vote



          accepted










          It should be clear, but the language specification never said that mismatched return types would have any effect during overload resolution. Because of that, there was no rule that said to prefer Action over Func<Task>. If Action would be picked, sure, it would work. If Func<Task> would be picked, then sure, you'd get an error. But to pick either, overload resolution has to succeed, and it isn't taking this into account.



          This is supposed to be fixed with new overload resolution in C# 7.3.






          share|improve this answer
















          • 8




            To confirm: yes, it is fixed in 7.3; adding <LangVer>7.3</LangVer> to a test project makes it resolve correctly
            – Marc Gravell♦
            Aug 14 at 9:18






          • 1




            It was a pretty obvious bug in the specification.
            – Joshua
            Aug 14 at 17:25














          up vote
          24
          down vote



          accepted










          It should be clear, but the language specification never said that mismatched return types would have any effect during overload resolution. Because of that, there was no rule that said to prefer Action over Func<Task>. If Action would be picked, sure, it would work. If Func<Task> would be picked, then sure, you'd get an error. But to pick either, overload resolution has to succeed, and it isn't taking this into account.



          This is supposed to be fixed with new overload resolution in C# 7.3.






          share|improve this answer
















          • 8




            To confirm: yes, it is fixed in 7.3; adding <LangVer>7.3</LangVer> to a test project makes it resolve correctly
            – Marc Gravell♦
            Aug 14 at 9:18






          • 1




            It was a pretty obvious bug in the specification.
            – Joshua
            Aug 14 at 17:25












          up vote
          24
          down vote



          accepted







          up vote
          24
          down vote



          accepted






          It should be clear, but the language specification never said that mismatched return types would have any effect during overload resolution. Because of that, there was no rule that said to prefer Action over Func<Task>. If Action would be picked, sure, it would work. If Func<Task> would be picked, then sure, you'd get an error. But to pick either, overload resolution has to succeed, and it isn't taking this into account.



          This is supposed to be fixed with new overload resolution in C# 7.3.






          share|improve this answer












          It should be clear, but the language specification never said that mismatched return types would have any effect during overload resolution. Because of that, there was no rule that said to prefer Action over Func<Task>. If Action would be picked, sure, it would work. If Func<Task> would be picked, then sure, you'd get an error. But to pick either, overload resolution has to succeed, and it isn't taking this into account.



          This is supposed to be fixed with new overload resolution in C# 7.3.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Aug 14 at 9:16









          hvd

          111k11187266




          111k11187266







          • 8




            To confirm: yes, it is fixed in 7.3; adding <LangVer>7.3</LangVer> to a test project makes it resolve correctly
            – Marc Gravell♦
            Aug 14 at 9:18






          • 1




            It was a pretty obvious bug in the specification.
            – Joshua
            Aug 14 at 17:25












          • 8




            To confirm: yes, it is fixed in 7.3; adding <LangVer>7.3</LangVer> to a test project makes it resolve correctly
            – Marc Gravell♦
            Aug 14 at 9:18






          • 1




            It was a pretty obvious bug in the specification.
            – Joshua
            Aug 14 at 17:25







          8




          8




          To confirm: yes, it is fixed in 7.3; adding <LangVer>7.3</LangVer> to a test project makes it resolve correctly
          – Marc Gravell♦
          Aug 14 at 9:18




          To confirm: yes, it is fixed in 7.3; adding <LangVer>7.3</LangVer> to a test project makes it resolve correctly
          – Marc Gravell♦
          Aug 14 at 9:18




          1




          1




          It was a pretty obvious bug in the specification.
          – Joshua
          Aug 14 at 17:25




          It was a pretty obvious bug in the specification.
          – Joshua
          Aug 14 at 17:25












           

          draft saved


          draft discarded


























           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f51837722%2fwhy-is-the-call-ambiguous-task-runaction-and-task-runfunctask%23new-answer', 'question_page');

          );

          Post as a guest













































































          這個網誌中的熱門文章

          How to combine Bézier curves to a surface?

          Carbon dioxide

          Why am i infinitely getting the same tweet with the Twitter Search API?