Mor*_*iya 103 c# asynchronous async-await
我目前正在尝试使用一些异步方法来创建我的应用程序.我的所有IO都是通过接口的显式实现完成的,我对如何使操作异步感到困惑.
在我看到的情况下,我在实现中有两个选项:
interface IIO
{
void DoOperation();
}
Run Code Online (Sandbox Code Playgroud)
OPTION1: 执行隐式实现异步并等待隐式实现中的结果.
class IOImplementation : IIO
{
async void DoOperation()
{
await Task.Factory.StartNew(() =>
{
//WRITING A FILE OR SOME SUCH THINGAMAGIG
});
}
#region IIO Members
void IIO.DoOperation()
{
DoOperation();
}
#endregion
}
Run Code Online (Sandbox Code Playgroud)
选项2: 显式实现异步并等待隐式实现中的任务.
class IOAsyncImplementation : IIO
{
private Task DoOperationAsync()
{
return new Task(() =>
{
//DO ALL THE HEAVY LIFTING!!!
});
}
#region IIOAsync Members
async void IIO.DoOperation()
{
await DoOperationAsync();
}
#endregion
}
Run Code Online (Sandbox Code Playgroud)
这些实现中的一个是否比另一个更好,还是有另一种方法可以解决这个问题?
svi*_*ick 208
这些选项都不正确.您正在尝试异步实现同步接口.不要那样做.问题是DoOperation()返回时,操作还不完整.更糟糕的是,如果在操作期间发生异常(这在IO操作中非常常见),则用户将没有机会处理该异常.
您需要做的是修改接口,使其成为异步:
interface IIO
{
Task DoOperationAsync(); // note: no async here
}
class IOImplementation : IIO
{
public async Task DoOperationAsync()
{
// perform the operation here
}
}
Run Code Online (Sandbox Code Playgroud)
这样,用户将看到操作是async并且他们将能够进行操作await.这也几乎迫使你的代码用户切换到async,但这是不可避免的.
另外,我假设StartNew()在您的实现中使用只是一个示例,您不应该需要实现异步IO.(而且new Task()更差,甚至不会工作,因为你不知道Start()的Task.)
Dim*_*ima 15
更好的解决方案是为异步操作引入另一个接口.新接口必须从原始接口继承.
例:
interface IIO
{
void DoOperation();
}
interface IIOAsync : IIO
{
Task DoOperationAsync();
}
class ClsAsync : IIOAsync
{
public void DoOperation()
{
DoOperationAsync().GetAwaiter().GetResult();
}
public async Task DoOperationAsync()
{
//just an async code demo
await Task.Delay(1000);
}
}
class Program
{
static void Main(string[] args)
{
IIOAsync asAsync = new ClsAsync();
IIO asSync = asAsync;
Console.WriteLine(DateTime.Now.Second);
asAsync.DoOperation();
Console.WriteLine("After call to sync func using Async iface: {0}",
DateTime.Now.Second);
asAsync.DoOperationAsync().GetAwaiter().GetResult();
Console.WriteLine("After call to async func using Async iface: {0}",
DateTime.Now.Second);
asSync.DoOperation();
Console.WriteLine("After call to sync func using Sync iface: {0}",
DateTime.Now.Second);
Console.ReadKey(true);
}
}
Run Code Online (Sandbox Code Playgroud)
PS重新设计你的异步操作,所以他们返回Task而不是void,除非你真的必须返回void.
| 归档时间: |
|
| 查看次数: |
87493 次 |
| 最近记录: |