2017-08-11 62 views
1

我有一个应用程序通过网络发送消息,并且我希望在等待消息发送和响应的同时执行其他工作。我通过调用启动Messaging进程“等待SendMessageAsync”,它具有以下职责:如何使用Task.Run如果使用库不支持异步等待

public async Task<bool> SendMessageAsync() 
{ 
    //Do Some Work 
    //Send First Message 
    //More Work 
    //Send Second Message 
    //More Work 
    //Send Third Message 
} 

如果我的第三方库的支持,我会写这样的:

public async Task<bool> SendMessageAsync() 
{ 
    //Do Some Work 
    await LibrarySendMessageAsync(firstMessage); 
    //More Work 
    await LibrarySendMessageAsync(secondMessage); 
    //More Work 
    await LibrarySendMessageAsync(thirdMessage); 
} 

然而SendMessageAsync是超时无法正常工作。所以我需要引入一些并行性并使用Task.Run。

我的问题是:将上面的整个方法包装在Task.Run中,还是将每个SendMessage方法包装在它自己的Task.Run中会更好?

public async Task<bool> SendMessageAsync() 
{ 
    //Do Some Work 
    await Task.Run(() => LibrarySendMessage(firstMessage)); 
    //More Work 
    await Task.Run(() => LibrarySendMessage(secondMessage)); 
    //More Work 
    await Task.Run(() => LibrarySendMessage(thirdMessage)); 
} 

VS

public async Task<bool> SendMessageAsync() 
{ 
    await Task.Run(() => 
    { 
    //Do Some Work 
    LibrarySendMessage(firstMessage); 
    //More Work 
    LibrarySendMessage(secondMessage); 
    //More Work 
    LibrarySendMessage(thirdMessage); 
    }); 
} 

性能(速度)是该应用程序非常重要。 SendMessageAsync将以高频率重复调用。

+0

你真的需要分析代码来获得一个合适的回答。通常我不会想象它会以任何方式产生重大差异,但是由于您以高频重复地调用它,然后将它封装在一个Task中。运行可能会节省您创建任务的开销。分析您的实际代码是这种情况下的方式,因为会涉及太多因素。 – Puddler

+1

个人我会做你的第二种方法的变体。删除Task.Run,​​将函数重命名为'SendMessage()',然后用'var result = await Task.Run((=)SendMessage())调用它;' –

+0

需要考虑的问题: 单个执行'SendMessageAsync'必须更快Vs对'SendMessageAsync'的大量调用必须更快 您的方法应该“尽可能快”,而您的整体程序吞吐量应该很大(可伸缩性) 正如您所看到的那样:'async '在C#意义上并不会让你的方法运行得更快。它[不会创建新线程](https://blog.stephencleary.com/2013/11/there-is-no-thread.html)。 – Subbu

回答

2

这取决于。 在一个Task.run中包装整个事物在逻辑上更简单。一旦创建任务,三条消息就会同步发送。同步代码总是比较容易编写,读取和调试

它在性能方面更加复杂。在这两种情况下,3个消息都按照有序的顺序发送。

三个Task.Runs消耗较少的线程(线程返回到池的速度更快),但会创建更多的任务以及承担从一个任务转换到另一个任务的成本。一个任务将导致线程阻塞更长的时间,然后是必要的。您将需要线程池中的更多线程来处理相同数量的消息。您将平衡唤醒线程以继续执行并从队列中选择任务以继续执行的成本。

余额将取决于发送3条消息需要多长时间,您可以承担多少线程池线程,预期通过的次数以及消息到达的模式(均匀还是零星) 。当然,最终一切都取决于分析。

+0

感谢您的回应! – MattHH

2

基本上你的第二个选项...你有一个方法: -

public async Task<bool> SendMessageAsync() 

,基本上不应该是异步。你是说基本上你想要的方法是同步的....所以编写方法

public bool SendMessage() 
{ 
    //Do Some Work 
    LibrarySendMessage(firstMessage); 
    //More Work 
    LibrarySendMessage(secondMessage); 
    //More Work 
    LibrarySendMessage(thirdMessage); 
} 

不要写怪异困惑异步方法同步代码。所以,那么,如果你想要做的工作在一个线程等待,然后...

await Task.Run(() => SendMessage()); 

,你可以换到你原来的方法SendMessageAsync

+0

感谢您的回应!收到关于可读性的消息并将其分解出来。 – MattHH