Click here to Skip to main content
14,367,300 members
Rate this:
Please Sign up or sign in to vote.
Please refer below for the several options to call a function with async/await.
I put my questions below each option.
Lets assume I have a 3rd party Dll and want to call a function of it asynchronously. Despite there is a function description one cannot know what actually happens inside:
/// <summary>
///  The function of a C# DLL to call. It reads data from a device.
/// </summary>
/// <param name="dataMsgs">
/// output structure for "signal data" (double) per "channel id" (Int32)
/// </param>
void DllTestFunction(Dictionary<Int32, double> dataMsgs);


First attempt to call that function asynchronously:
public class DriverTestViewModel
{
  private readonly Dictionary<Int32, double> _dataDictionaryForDll;

  private async Task CallDllTestFunctionAsync()
  {
    // Option 1, one-liner async call 
    await Task.Run(() => DllTestFunction(_dataDictionaryForDll)).ConfigureAwait( 
    false );
  }
}

Q1: Is there anything wrong yet in the attempt to encapsulate the "ordinary" function in an async call? I'm asking that since I found trivial examples only yet. E.g.:
await Task.Delay(TimeSpan.FromSeconds(2)); 
// or by calling an existing async .Net function like FileStream.ReadAsync()
await SourceStream.ReadAsync(result, 0, (int)SourceStream.Length);

Both trivial examples are not calling Task.Run() or Task.Start(), which is pretty confusing.
Q2: I assume this is done inside Task.Delay() and FileStream.ReadAsync(), is it?

But there is more to ask:
// Option 2, split into two calls
var dllTask = Task.Run(() => DllTestFunction(_dataDictionaryForDll));
await dllTask.ConfigureAwait( false );

Q3: I assume both implementation options 1 and 2 are fully equivalent, are they?

Then one can split up more:
// Option 3, separate calls even more
var dllTask = Task.Run(() => DllTestFunction(_dataDictionaryForDll));
dllTask.ConfigureAwait(false); // compiler warning
await dllTask;

A compiler warning is issued stating that the call is not awaited.
Q4: Why is that and can the warning be safely ignored as long as the await call follows?

Finally the option 3, the task is created on its own and Start() is used on the instance rather than the shared Task.Run() call.
// Option 3, fully split
var dllTask = new Task(() => DllTestFunction(_dataDictionaryForDll));

dllTask.Start(); // instance call vs. shared Task.Run()
await dllTask.ConfigureAwait( false ); 

Q5: I assume implementation options 1,2 and 3 are equivalent regarding the async processing, are they?

Q6: What is the difference in executing functions A,B,C in a row as illustrated in the example below?
Q7: When should the shared call be avoided?
// instance call
  A.Start();
  B.Start();
  C.Start();
// vs. shared call
  Task.Run(A);
  Task.Run(B);
  Task.Run(C);
Posted
Comments
Philippe Mori 24-Aug-15 13:56pm
   
Too much questions in one. Ask each question separately!
Chris875 27-Aug-15 10:20am
   
All questions refer to the same context. I thought it makes sense to list them. Please note that each question can be referred to with Q1, Q2, ...
Philippe Mori 27-Aug-15 11:29am
   
It is up to you but you won't get many answers doing it that way.

Between groups of questions {1,2}, {3,4,5} and {6,7} there are almost no common context.
virusstorm 25-Aug-15 15:03pm
   
You have a lot of questions here making it really hard to give you an answer to anything. What I can tell you, because I think they all relate back to this, is you should not build async/await wrapper around a DLL import. The async/await pattern in .NET runs with in the .NET world. There are internal structures that get created and manged internally by .NET. When you perform a DLL import, you are leaving managed code and going into unmanaged code. When you do this, .NET no longer has the ability to control the task/thread the work is being done. It is highly recommended and advised that you use the async/await pattern with .NET objects that are designed to use this pattern. Hybrid approaches typically with have undesired effects.
Chris875 27-Aug-15 10:19am
   
Well, all questions refer to the same context. Either I have to repeat the context over and over again. Or I summarize all questions below the context.
So i opted for the second method. You could answer a single question by referring to its number "Q4". I think it is not too much effort, is it?

But back to the subject: I can't see that i referred to a unmanaged Dll import anywhere. It's all about managed .NET Dlls. The point is, that the Dll does not provide any method with async/await signature. So how to use them anyway with the Task Asynchronous Pattern (TAP)?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100