繁体   English   中英

是否可以同步调用异步调用?

[英]Is it possible to call an Asynchronous call Synchronously?

我已经在我想要做的事情下面放了一些非常基本的代码。 我有'DoSomethingAshnc'方法执行异步操作。 我希望'DoSomething'方法是一个不接受action参数并返回int的同步方法。

public void DoSomething(Action<int> actionToPerformOnComplete)
    {
        DoSomethingAsync(delegate(int val)
            {
                actionToPerformOnComplete(val);
            });
    }

是否甚至可以让'DoSomething'返回一个整数,就像方法同步发生一样?

您需要在同步方法的最后添加一些内容,告诉它等待另一个调用完成。 我假设您的异步方法将有一个事件告诉调用者何时完成。

如果是这样,那么我建议使用像ManualResetEvent这样的东西,在同步线程中等待它,并在异步事件的Finish事件接收器中设置它。

例:

public void DoSomething(Action<int> actionToPerformOnComplete)
{
   ManualResetEvent mre = new ManualResetEvent(false);
   DoSomethingAsync(delegate(int val)
   {
      try
      {
         actionToPerformOnComplete(val);
      }
      finally
      {
         mre.Set();
      }
   });
   mre.WaitOne();
}

是。 你所要做的就是把这行代码:

IAsyncResult asycn = ... // make a call to Async and get back IAsyncResult 
while(!asycn.IsCompleted)
{
   Thread.Sleep( ....);
}

UPDATE

正如一些人所问,正确设计的异步操作将实现异步模式 MSDN:

使用IAsyncResult设计模式的异步操作实现为名为BeginOperationName和EndOperationName的两个方法,分别开始和结束异步操作OperationName。 例如,FileStream类提供BeginRead和EndRead方法,以异步方式从文件中读取字节。 这些方法实现了Read方法的异步版本。

正如其他人所提到的,您需要等待异步方法完成。 要在不将Action参数传递给方法的情况下执行此Action ,请使用以下代码:

public int DoSomething()
{
   int result;
   ManualResetEvent mre = new ManualResetEvent(false);
   DoSomethingAsync(val => {result = val; mre.Set(); });
   mre.WaitOne();
   return result;
}

这将执行异步方法,等待它完成并将结果分配给局部变量。 返回此结果。

using System;
using System.Threading;

namespace qqq
{
    class Program
    {
        public static void DoAsync(Action<int> whenDone)
        {
            new Thread(o => { Thread.Sleep(3000); whenDone(42); }).Start();
        }

        static public int Do()
        {
            var mre = new ManualResetEvent(false);

            int retval = 0;
            DoAsync(i => { retval = i; mre.Set(); });

            if (mre.WaitOne())
                return retval;
            throw new ApplicationException("Unexpected error");
        }

        static void Main(string[] args)
        {
            Console.WriteLine(Do());
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM