C# 如何创建立即完成的IAsyncResult?
我正在实现一个接口,它需要实现C# 如何创建立即完成的IAsyncResult?,c#,.net,asynchronous,delegates,iasyncresult,C#,.net,Asynchronous,Delegates,Iasyncresult,我正在实现一个接口,它需要实现BeginDoSomething和EndDoSomething方法。然而,我的DoSomething并不是真正的长期运行。 为简单起见,假设DoSomething仅比较两个变量并返回a>b 所以我的开始应该是这样的: protected override IAsyncResult BeginDoSomething(int a, int b, AsyncCallback callback, object state) { bool returnValue =
BeginDoSomething
和EndDoSomething
方法。然而,我的DoSomething
并不是真正的长期运行。
为简单起见,假设DoSomething
仅比较两个变量并返回a>b
所以我的开始应该是这样的:
protected override IAsyncResult BeginDoSomething(int a, int b, AsyncCallback callback, object state)
{
bool returnValue = a > b;
return ...; //what should I return here?
//The method actually already completed and I don't need to wait for anything
}
我不知道该还什么。我之所以实现
begindomething
,是因为我必须这样做,而不是因为我的方法是长期运行的。我是否需要实现自己的IAsyncResult
?.NET库中已经有实现了吗?这有点快,但您可以实现实现IAsyncResult的类,如下所示:
public class MyAsyncResult : IAsyncResult
{
bool _result;
public MyAsyncResult(bool result)
{
_result = result;
}
public bool IsCompleted
{
get { return true; }
}
public WaitHandle AsyncWaitHandle
{
get { throw new NotImplementedException(); }
}
public object AsyncState
{
get { return _result; }
}
public bool CompletedSynchronously
{
get { return true; }
}
}
然后在开始时使用它,比如:
return new MyAsyncResult(a > b);
快速破解的方法是使用委托:
protected override IAsyncResult BeginDoSomething(int a, int b, AsyncCallback callback, object state)
{
bool returnValue = a > b;
Func<int,int,bool> func = (x,y) => x > y;
return func.BeginInvoke(a,b,callback,state);
}
protected override IAsyncResult BeginDoSomething(int a、int b、AsyncCallback、object state)
{
布尔返回值=a>b;
Func Func=(x,y)=>x>y;
返回函数BeginInvoke(a、b、回调、状态);
}
这种方法的缺点是,如果两个线程同时调用此方法,您需要小心,否则会出现错误。我不确定是否遗漏了某些内容,但今天您可以返回
任务。CompletedTask
/任务。FromResult
<代码>任务实现IAsyncResult
protected override IAsyncResult BeginDoSomething(int a, int b, AsyncCallback callback, object state)
{
return Task.FromResult(a > b);
}
这里的
IAsyncResult.IsCompleted
正确地true
。Func.BeginInvoke
方法不会产生正确的结果。我建议您按照说明使用基于任务的方法创建实现,以防其中一种方法长时间运行。如果DoSomething短期运行,您可以通过根据其结果创建一个任务来阻止它
public IAsyncResult BeginDoSomething(int a, int b,
AsyncCallback callback,
object state)
{
return Task.FromResult(DoSomething(a, b)).AsApm(callback, state);
}
public bool EndDoSomething(IAsyncResult asyncResult)
{
return ((Task<bool>)asyncResult).Result;
}
bool DoSomething(int a, int b)
{
return a > b;
}
public static IAsyncResult AsApm<T>(this Task<T> task,
AsyncCallback callback,
object state)
{
if (task == null)
throw new ArgumentNullException("task");
var tcs = new TaskCompletionSource<T>(state);
task.ContinueWith(t =>
{
if (t.IsFaulted)
tcs.TrySetException(t.Exception.InnerExceptions);
else if (t.IsCanceled)
tcs.TrySetCanceled();
else
tcs.TrySetResult(t.Result);
if (callback != null)
callback(tcs.Task);
}, TaskScheduler.Default);
return tcs.Task;
}
public IAsyncResult BeginDoSomething(int a、int b、,
异步回调,
对象状态)
{
返回Task.FromResult(DoSomething(a,b)).AsApm(回调,状态);
}
公共布尔EndDoSomething(IAsyncResult asyncResult)
{
返回((任务)asyncResult).Result;
}
布尔剂量测定法(内部a、内部b)
{
返回a>b;
}
公共静态IAsyncResult AsApm(此任务,
异步回调,
对象状态)
{
如果(任务==null)
抛出新异常(“任务”);
var tcs=新任务完成源(状态);
task.ContinueWith(t=>
{
如果(t.IsFaulted)
tcs.TrySetException(t.Exception.InnerException);
否则,如果(t.IsCanceled)
tcs.trysetconceled();
其他的
tcs.TrySetResult(t.Result);
if(回调!=null)
回调(tcs.Task);
},TaskScheduler.Default);
返回tcs.Task;
}
我认为AsyncWaitHandle
属性应该返回对集合ManualResetEvent
(或类似集合)的引用。客户端尝试等待句柄是完全合理的,这不应该导致抛出异常。诚然,我们可以这样做,但由于WaitHandle是一个昂贵的对象,在它永远都不相关的情况下创建它似乎是浪费。代码缺少回调调用,必需(如果不是null)。啊,⁺一个人必须只实现getter…这并不明显,我不明白为什么公共bool已完成
一直被称为未实现。实际上并不快,但很难与简单性争论。省略returnValue。我没有看到错误。那么,EndDoSomething
中应该有什么?很抱歉,我对异步编程非常陌生*它与func.BeginInvoke:IAsyncResult相同,因此您实际上是在将责任委托给委托的实现。func.EndInvoke?但func只在Begin*方法中声明,不能在End中调用*