代码之家  ›  专栏  ›  技术社区  ›  Pau

线程化多个异步调用

  •  6
  • Pau  · 技术社区  · 17 年前

    AutoResetEvent (链接到MSDN示例)线程,然后同步结果,但似乎无法将其用于异步服务调用。

    有没有人有任何理由怀疑这种方法,或者这种方法是否有效?代码样本收到!

    2 回复  |  直到 12 年前
        1
  •  7
  •   sth    16 年前

    看看这个例子:

    关键的是,等待自动resetEvents发生在后台线程中。


    public partial class MainPage : UserControl
    {
        public MainPage()
        {
            InitializeComponent();
    
            Completed += (s, a) => { Debug.WriteLine("done"); };
    
            wrk.DoWork += (s, a) =>
                {
                    Start();
                };
    
            wrk.RunWorkerAsync();
        }
        public event EventHandler Completed;
    
        private void Start()
        {
            auto1.WaitOne();
            auto2.WaitOne();
    
            Completed(this, EventArgs.Empty);
        }
    
        public AutoResetEvent auto1 = new AutoResetEvent(false);
        public AutoResetEvent auto2 = new AutoResetEvent(false);
    
        BackgroundWorker wrk = new BackgroundWorker();
    
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            ServiceReference1.Service1Client clien = new SilverlightAsyncTest.ServiceReference1.Service1Client();
    
            clien.DoWorkCompleted += new EventHandler<SilverlightAsyncTest.ServiceReference1.DoWorkCompletedEventArgs>(clien_DoWorkCompleted);
            clien.DoWork2Completed += new EventHandler<SilverlightAsyncTest.ServiceReference1.DoWork2CompletedEventArgs>(clien_DoWork2Completed);
    
            clien.DoWorkAsync();
            clien.DoWork2Async();
        }
    
        void clien_DoWork2Completed(object sender, SilverlightAsyncTest.ServiceReference1.DoWork2CompletedEventArgs e)
        {
            Debug.WriteLine("2");
            auto1.Set();
        }
    
        void clien_DoWorkCompleted(object sender, SilverlightAsyncTest.ServiceReference1.DoWorkCompletedEventArgs e)
        {
            Debug.WriteLine("1");
            auto2.Set();
        }
    }
    
        2
  •  3
  •   Miguel Madero    17 年前

    可以使用每个异步方法返回的IAsyncResult中的WaitHandle来完成。

    代码很简单。在Silverlight中,我只做了10次服务调用,将一个项目添加到列表框中。我将等到所有服务调用结束后再向列表中添加另一条消息(这必须在不同的线程中运行,以避免阻塞UI)。还要注意,向列表中添加项目必须通过Dispatcher完成,因为它们将修改UI。有很多lamda,但很容易理解。

     public MainPage()
            {
                InitializeComponent();
                var results = new ObservableCollection<string>();
                var asyncResults = new List<IAsyncResult>();
                resultsList.ItemsSource = results;
                var service = new Service1Client() as Service1;
    
                1.To(10).Do(i=>
                    asyncResults.Add(service.BeginDoWork(ar =>
                        Dispatcher.BeginInvoke(() => results.Add(String.Format("Call {0} finished: {1}", i, service.EndDoWork(ar)))),
                        null))
                );
    
                new Thread(()=>
                {
                    asyncResults.ForEach(a => a.AsyncWaitHandle.WaitOne());
                    Dispatcher.BeginInvoke(() => results.Add("Everything finished"));
                }).Start();
            }
    

    public class Service1
        {
            private const int maxMilliSecs = 500;
            private const int minMillisSecs = 100;
            [OperationContract]
            public int DoWork()
            {
                int millisSecsToWait = new Random().Next(maxMilliSecs - minMillisSecs) + minMillisSecs;
                Thread.Sleep(millisSecsToWait);
                return millisSecsToWait;
            }
        }