Threading multiple async calls

后端 未结 2 1815
余生分开走
余生分开走 2021-01-01 00:41

Part of my Silverlight application requires data from three service requests. Up until now I\'ve been chaining the requests so as one completes the other starts... until the

相关标签:
2条回答
  • 2021-01-01 01:10

    It could be done using the WaitHandle in the IAsyncResult returned by each async method.

    The code is simple. In Silverlight I just do 10 service calls that will add an item to a ListBox. I'll wait until all the service calls end to add another message to the list (this has to run in a different thread to avoid blocking the UI). Also note that adding items to the list have to be done through the Dispatcher since they will modify the UI. There're a bunch of lamdas, but it's easy to follow.

     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();
            }
    

    Just to help with the testing, this is the service

    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;
            }
        }
    
    0 讨论(0)
  • 2021-01-01 01:12

    Take a look at this example:

    Will fire Completed event and print 'done' to Debug Output once both services returned. Key thing is that waiting for AutoResetEvents happens in background thread.


    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();
        }
    }
    
    0 讨论(0)
提交回复
热议问题