As detailed in the TPL and Traditional .NET Framework Asynchronous Programming MSDN article and Stephen Toub's Tasks and the APM Pattern blog post, the TaskFactory.FromAsync() and TaskFactory<TResult>.FromAsync() methods can be used to adapt Begin*() and End*() APIs conforming to the APM pattern for use with the Task Parallel Library.
Below I will address only the TaskFactory<TResult>.FromAsync() overloads, as my question does not depend on whether the APM-conforming APIs result in a value.
There are three overloads that accept an IAsyncResult object, namely:
FromAsync(IAsyncResult, Func<IAsyncResult, TResult>)FromAsync(IAsyncResult, Func<IAsyncResult, TResult>, TaskCreationOptions)FromAsync(IAsyncResult, Func<IAsyncResult, TResult>, TaskCreationOptions, TaskScheduler)
I understand that these APIs are useful in scenarios where the Begin*() API method takes more than three parameters in addition to the AsyncCallback and state object (e.g. Too many arguments in BeginXXX for FromAsync?), or when the Begin*() API does not fully conform to the APM pattern because it does not take a state object parameter (e.g. How can I use the AsyncCTP with an TFS APM Method (Query.Begin/EndQuery)?).
What I don't understand is why the remaining overloads (e.g. FromAsync(Func<AsyncCallback, Object, IAsyncResult>, Func<IAsyncResult, TResult>, Object)) all require a state object to be supplied. This state object is passed to the Begin*() API, but in the APM pattern, the state object is for private use by the caller. So, it shouldn't matter what state object is passed to the Begin*() API by FromAsync().
The MSDN article linked above has a section titled "Providing Custom State Data" which recommends capturing any required state in a continuation delegate and passing null for the state object to FromAsync(). However, this does not explain why the FromAsync() methods require a state object to be given.
Why is a state object required to be passed when it is not accessible to the returned Task<TResult>?