C# 使接口实现异步
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14458566/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Making interface implementations async
提问by Moriya
I'm currently trying to make my application using some Async methods. All my IO is done through explicit implementations of an interface and I am a bit confused about how to make the operations async.
我目前正在尝试使用一些异步方法制作我的应用程序。我所有的 IO 都是通过接口的显式实现完成的,我对如何使操作异步有点困惑。
As I see things I have two options in the implementation:
正如我所见,我在实现中有两个选择:
interface IIO
{
void DoOperation();
}
OPTION1:Do an implicit implementation async and await the result in the implicit implementation.
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
}
OPTION2:Do the explicit implementation async and await the task from the implicit implementation.
OPTION2:异步执行显式实现并等待来自隐式实现的任务。
class IOAsyncImplementation : IIO
{
private Task DoOperationAsync()
{
return new Task(() =>
{
//DO ALL THE HEAVY LIFTING!!!
});
}
#region IIOAsync Members
async void IIO.DoOperation()
{
await DoOperationAsync();
}
#endregion
}
Are one of these implementations better than the other or is there another way to go that I am not thinking of?
这些实现中的一个比另一个更好还是有另一种我没有想到的方法?
采纳答案by svick
Neither of these options is correct. You're trying to implement a synchronous interface asynchronously. Don't do that. The problem is that when DoOperation()
returns, the operation won't be complete yet. Worse, if an exception happens during the operation (which is very common with IO operations), the user won't have a chance to deal with that exception.
这两个选项都不正确。您正在尝试异步实现同步接口。不要那样做。问题是当DoOperation()
返回时,操作还没有完成。更糟糕的是,如果在操作过程中发生异常(这在 IO 操作中很常见),用户将没有机会处理该异常。
What you need to do is to modify the interface, so that it is asynchronous:
您需要做的是修改 interface,使其异步:
interface IIO
{
Task DoOperationAsync(); // note: no async here
}
class IOImplementation : IIO
{
public async Task DoOperationAsync()
{
// perform the operation here
}
}
This way, the user will see that the operation is async
and they will be able to await
it. This also pretty much forces the users of your code to switch to async
, but that's unavoidable.
这样,用户将看到操作是async
并且他们将能够执行await
它。这也几乎迫使您的代码的用户切换到async
,但这是不可避免的。
Also, I assume using StartNew()
in your implementation is just an example, you shouldn't need that to implement asynchronous IO. (And new Task()
is even worse, that won't even work, because you don't Start()
the Task
.)
另外,我假设StartNew()
在您的实现中使用只是一个例子,您不需要它来实现异步 IO。(而且new Task()
是更糟糕,这甚至不会工作,因为你不知道Start()
的Task
。)
回答by Dima
Better solution is to introduce another interface for async operations. New interface must inherit from original interface.
更好的解决方案是为异步操作引入另一个接口。新接口必须继承原接口。
Example:
例子:
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);
}
}
P.S. Redesign your async operations so they return Task instead of void, unless you really must return void.
PS 重新设计您的异步操作,以便它们返回 Task 而不是 void,除非您确实必须返回 void。