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中调用*