Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
431 views
in Technique[技术] by (71.8m points)

c# - Calling an async method using a Task.Run seems wrong?

I recently came across this code written by a contractor we had working for us. It's either devilishly clever or silly (I think the latter but I wanted a second opinion). I'm not massively up to speed on async await.

Basically it worked like this:

public bool Send(TemplatedMessageDto message)
{
    return Task.Run(() => SendAsync(message))
        .GetAwaiter()
        .GetResult();
}

public async Task<bool> SendAsync(TemplatedMessageDto message)
{
    //code doing stuff
    var results = await _externalresource.DothingsExternally();
    //code doing stuff
}

Now as I understand it that first Task.Run() is pointless and inefficient? and should really be:

public bool Send(TemplatedMessageDto message)
{
    return SendAsync(message))
    .GetAwaiter()
    .GetResult();
}

public async Task<bool> SendAsync(TemplatedMessageDto message)
{
    //code doing stuff
    var results = await _externalresource.DothingsExternally();
    //code doing stuff
}

I'm also not convinced this is really an async method because it will still wait, right? I think it's only advantage (even re-written) is to free up the main worker thread.

Can someone confirm that this first Task shouldn't be there?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I'm also not convinced this is really an async method because it will still wait, right?

It isn't, as Yuval explained. You shouldn't use sync over async.

Now as I understand it that first Task.Run() is pointless and inefficient?

Not really, there is value in using Task.Run in such a way.

Since you're blocking on an async method (which you shouldn't do) there is a chance you'll deadlock. That happens in UI apps and asp.net where you have a SynchronizationContext.

Using Task.Run clears that SynchronizationContext since it offloads the work to a ThreadPool thread and removes the risk for a deadlock.

So, blocking is bad, but if you end up doing it using Task.Run is safer.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...