本帖最后由 xx_mm 于 2011-03-15 13:31:13 编辑

解决方案 »

  1.   

    可以:在 Lambda 表达式之前申明一个局部变量。在 Lambda 内部赋值。在代码块后可以使用。
      

  2.   


    这个Lambda 表达式是在方法中调用的,如何在之前声明呢?
    嗯,主要是解决办法不知道。
      

  3.   

    代码什么的都正常,就是代码运行至strAddress = nodeMsg.InnerXml 则运行不到return 语句,不知道有什么解决办法
      

  4.   

    IAsyncResult Ias = request.BeginGetResponse((ar1) =>整个都是异步的,和这个方法 GetAddressByGPS 主体异步了。因为你这个方法是要返回值的,所以建议你把方法改成同步的。
    即 request.GetResponse() 
      

  5.   

    你不同步,是不可能 GetAddressByGPS 里有返回值的。除非你都改为回调。比如 GetAddressByGPS 改为 void BeginGetAddressByGPS
    然后回调一个 EndGetAddressByGPS 
      

  6.   

    异步方式哪儿有这么用的...你这个方法是同步模式,你就只能等异步回调方法返回...在return前加个循环等待...
      

  7.   

    如果是这种该怎么写呢?因为我需要返回值形式的,void不符合
      

  8.   

    加个标识就行了...bool noReturn=true;在catch块后面改标识...noReturn=false;在return前等待...while(noReturn){Thread.Sleep(1);}
    return strAddress;
      

  9.   

    最好加上超过,以免死循环...
    var start = DateTime.Now;
    while(noReturn && DateTime.Now.Subtract(start).Seconds<30){Thread.Sleep(1);}
    return strAddress;
      

  10.   

    这个 EndGetAddressByGPS 就是 (ar1) => { ... }; 这部分,你抽出来做一个方法这个方法不是“你”调用,而是Begin里回调的。
    void EndGetAddressByGPS(IAsyncResult asynchronousResult)
    {
       ...
    }strAddress 如果是给UI赋值,可以直接在里面做。但要用跨线程的Invoke。
    比如:
    Action<string> action = (str)=>{ this.Label1.Text = str; };
    this.Label1.Invoke(action, strAddress);
      

  11.   


    在异步代码后加等待你这不是同步么?直接request.GetResponse()得了。费那劲
      

  12.   

    fangxinggood 急求明确答案。。
      

  13.   

    异步的具体该那怎么写呢?vrhero。。求助!
      

  14.   

    告诉你个最简单的方法...在你那个类中声明个事件,在catch块后面触发事件,你那方法不需要返回值了也不用改异步方法...调用者直接订阅事件接收数据...
      

  15.   

    Form调用这个类是否要返回值,如果要你就改为request.GetResponse()。
    要返回值就必须同步,就不能用BeginGetResponse()。非要用BeginGetResponse(),就不能有返回值。
    不知道你UI和这个类啥关系能把表示的控件往这个类里传吗?
      

  16.   

    恩,Form调用这个类里的GetAddressByGPS方法,然后得到值传给DataGridView中的一个单元格,而且这个DataGridView 有很多行,那一列的每个单元格都要进行处理,所以如果不异步的话性能会很差甚至出现假死,真的没别的办法吗?
      

  17.   

    有办法的。看你这个回调咋写了vrhero说的event也是回调的一种实现。
      

  18.   

    参考using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using System.Threading;namespace BeginInvoke
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }        private void Form1_Load(object sender, EventArgs e)
            {
                DataTable data = new DataTable();
                data.Columns.Add("col1");
                data.Columns.Add("col2");
                data.Columns.Add("col3");            data.Rows.Add(new object[] { "11", "12", "" });
                data.Rows.Add(new object[] { "21", "22", "" });
                data.Rows.Add(new object[] { "31", "32", "" });
                data.Rows.Add(new object[] { "41", "42", "" });            this.dataGridView1.DataSource = data;
            }        private void button1_Click(object sender, EventArgs e)
            {
                DataTable data = (DataTable)this.dataGridView1.DataSource;
                YourSomeClass yourClass = new YourSomeClass();
                yourClass.OnGetAddress += yourClass_OnGetAddress;
                foreach (DataRow row in data.Rows)
                {
                    //为了知道是哪一行数据获得了,我把行号传进去了。
                    var index = data.Rows.IndexOf(row);
                    yourClass.GetAddressByGPS(0, 0, (object)index);
                }
                
            }        void yourClass_OnGetAddress(object arg1, string arg2)
            {
                DataTable data = (DataTable)this.dataGridView1.DataSource;
                var index = (int)arg1;
                data.Rows[index][data.Columns.Count-1] = arg2;
            }
        }    public class YourSomeClass
        {
            public event Action<object, string> OnGetAddress;        public void GetAddressByGPS(double longitude, double latitude, object vehicleInfo)
            {
                //你原来的逻辑
                //我这里模拟你的BeginGetResponse
                Action action = SomeWork;
                action.BeginInvoke((ar) => {
                    string strAddress = "";
                    try
                    { 
                        //...
                        strAddress = "GetAddressSuccess";
                    }
                    catch (Exception ex)
                    { 
                        //...
                        strAddress = "GetAddressFailure";
                    }                //这里我把vehicleInfo作为区分你需要更新数据的Key
                    if (OnGetAddress != null)
                        OnGetAddress(vehicleInfo, strAddress);
                                
                }, null);
            }        private void SomeWork()
            {
                Thread.Sleep(5000);
            }    }
    }
      

  19.   

    fangxinggood,先大大的谢谢你了!
    我现在回宿舍了,明早上班我就测试下!看能否实现,不过感觉是可行的。。可能具体的细节到时还要请教你哦。。
      

  20.   

    还有感谢vrhero  ,你们真的很牛。。也很热心。。
      

  21.   

    fangxinggood 看下,我在宿舍用电脑模拟测试了一个例子你看看原理是不是你说的:一个窗体,一个类EveClass 包含核心方法DealValue,
    调用类代码分别为:
    using System;
    using System.Threading;namespace ChuFaEvent
    {
        public class EveClass
        {
            public event Action<int> OnGetValue;
            public void DealValue(int val)
            {
                Action action = DoSomeWork;
                action.BeginInvoke((ar) =>
                {                int temp = val * 100;
                    if (OnGetValue != null)
                    {
                        OnGetValue(temp);
                    }
                } , null);
            }
            private void DoSomeWork()
            {
                Thread.Sleep(3000);
            }
        }
    }窗体代码:
    using System;
    using System.Windows.Forms;namespace ChuFaEvent
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();        }
            private void button1_Click(object sender , EventArgs e)
            {
                EveClass Ec = new EveClass();
                Ec.OnGetValue += new Action<int>(Ec_OnGetValue);
                for (int i = 0; i < 10; i++)
                {
                    Ec.DealValue(i);
                }        }
            void Ec_OnGetValue(int obj)
            {
                this.Invoke((MethodInvoker)(() =>
                {
                    listBox1.Items.Add(obj);
                }));        }
        }
    }效果如下:
      

  22.   

    调用对应的END方法即可。。也就是你返回的时候begin并没有执行完成。。所以你就反回一个空的了。调用end等待完成再返回
      

  23.   

    恩,是这个原理,在BeginInvoke结束之时,引发一个Event,而这个Event在Form侧监听。
    Form侧在事件中更新自己控件的数据。但,另外一个问题在于怎么区别不同单元格返回的数据上。
      

  24.   

    可以了,谢谢楼上各位的解答,尤其fangxinggood ,vrhero解答