Calling async function from unmanaged code in the main thread

D Sanchen 1 Reputation point
2020-11-19T18:38:20.427+00:00

Hi there,
I have an unmanaged application (not written with Visual Studio) that needs to call WCF Services from within the main thread. Additionally, this app also acts as a COM server with all COM objects in the STA, where the main thread of the app is the STA-Thread.
For calling the WCF service(s) I wrote a mixed mode DLL where the native part can be called by my unmanaged app. The callable functions of the DLL are all static __stdcall functions, delegating their work to some managed classes, especially some WCF proxies, which do the actual call to WCF.
There is one COM client connected to my app, that calls into my app every 100ms or so, causing a call to WCF. Within my app, I have another component, that also needs to call the same WCF-Function in a regular interval, also approximately every 100ms. The WCF function I'm calling returns a Task<T>, on which I need to wait before I can go on.
Now the question is, how do I correctly wait for the task that is returned by the WCF-function in my unmanaged main thread ?? Obviously, I need to return from the WCF call in the same (main) thread. I tried using ->GetAwaiter().GetResult(), which sometimes (not always !) causes a dealock on the main thread, which in turn causes a Client-Side OperationTimeout of the WCF function.
Any help would be greatly appreciated !

.NET
.NET
Microsoft Technologies based on the .NET software framework.
3,914 questions
{count} votes

1 answer

Sort by: Most helpful
  1. D Sanchen 1 Reputation point
    2020-11-23T07:55:42.373+00:00

    Hi TheobaldDuShanghaiWicresoftCoLtd-3477

    The exception I get on the client side is the following (I replaced my class and function names by UPPERCASE placeholders...)

    MYPROXYCLASS.MYPROXYFUNCTION_Async<>: <INTERFACEFUNC_Async>b__0, caller: INTERFACEFUNC_Async, caught System.TimeoutException: This request operation sent to net.pipe://...MYSERVICEPATH... did not receive a reply within the configured timeout (00:00:10). The time allotted to this operation may have been a portion of a longer timeout. This may be because the service is still processing the operation or because the service was unable to send a reply message. Please consider increasing the operation timeout (by casting the channel/proxy to IContextChannel and setting the OperationTimeout property) and ensure that the service is able to connect to the client.
    at System.Runtime.AsyncResult.EndTAsyncResult
    at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.End(SendAsyncResult result)
    at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
    at System.ServiceModel.Channels.ServiceChannelProxy.TaskCreator.<>c__DisplayClass7_01.<CreateGenericTask>b__0(IAsyncResult asyncResult) at System.Threading.Tasks.TaskFactory1.FromAsyncCoreLogic(IAsyncResult iar, Func2 endFunction, Action1 endAction, Task1 promise, Boolean requiresSynchronization) --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.ConfiguredTaskAwaitable1.ConfiguredTaskAwaiter.GetResult()
    at MYPROXYCLASS1.<MYPROXYFUNCTION_Async>d__71.MoveNext()

    The service side is completely unaware of this.
    I know that the server answers in a few milliseconds, so extending the timeout of the call will only cause the timeout to happen later...

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.