通过线程循环读取数据,数据发生改变后,输出不变。

[DllImport("1.dll", EntryPoint = "fuck1", CharSet = CharSet.Auto)]
public static extern void fuck1(Int64 pid, Int64 address, out byte buf, int size);

private void xc1()
{
Int64 pid = int.Parse(textBox2.Text);
Int64 address = Convert.ToInt64(textBox4.Text);
byte m;
int size = int.Parse(textBox6.Text);
LD = true;
times = 0;

        while (LD)
        {
            Thread.Sleep(100);

            fuck1(pid, address, out m, size);

            try
            {
                textBox7.Text = m.ToString();
                Console.WriteLine(m);
                label8.Text = (times += 1).ToString();
            }
            catch (Exception e)
            {

            }
        }
    }
我通过 fuck1函数读取数据。循环读取数据的时候,如果数据改变输出的数据不改变。
但是不用循环,单词读取的时候数据改变以后再读取,就能读取到正确的值,请问一下为什么?

2个回答

两种写法给你:
一:直接在UI线程里面死循环(就是你这种写法:加上Application.DoEvents()这句)
while (LD)
{
Thread.Sleep(100);

        fuck1(pid, address, out m, size);

        try
        {
            textBox7.Text = m.ToString();
            Console.WriteLine(m);
            label8.Text = (times += 1).ToString();
        }
        catch (Exception e)
        {

        }
                    Application.DoEvents();
    }

第二种写法(启动另外的线程去做循环,然后使用invoke()方法显示UI)
Thread td = new Thread(()=>{
while (LD)
{
Thread.Sleep(100);

        fuck1(pid, address, out m, size);

        try
        {
                        this.Invoke(new Action(()=>{
            textBox7.Text = m.ToString();
            Console.WriteLine(m);
            label8.Text = (times += 1).ToString();
                            }));
        }
        catch (Exception e)
        {

        }
    }

})
td.IsBackground = true;
td.Start();

//以上两种方法都可以,然后解释一下为什么你那样不行,因为你再UI线程里面使用了死循环而且调用了Sleep()函数,你要理解Sleep()函数会使当前线程挂起,不接受任何消息,所以更新界面的消息自然不会被处理,所以你看到输出值不变,其实这个值一直在变,只不过你看不到罢了,另外你这样写出来的Form肯定是特别的“卡”,拖都拖不动,点上面的任何控件都不会有响应
,然后说下加Application.DoEvents()就可以的原因,是因为调用这个函数后即使你挂起UI线程,但是窗体仍然会处理响应各种消息
第二种方法就是把循环写到另外一个线程,然后通过Invoke()方法回调显示结果,所以此时UI线程不会假死不会被挂起,所以可以正常更新界面

hxycsdn9159
hxycsdn9159 回复hcli168:UI线程都是STA模式的单元线程应该不会允许你在其他线程操作控件的 ,如果你是在非UI线程去操作界面的控件应该会抛“跨线程操作对象”的异常,除非你把线程安全监测的属性设置为false,至于你说你看的是控制台你可以注意下是不是你给textbox赋值之后代码就已经抛异常被cach掉了,所以后面控制台打印的代码根本没执行造成的
一年多之前 回复
hcli168
waesaeasea 我上面的代码是通过线程的启动的,界面不会卡死,Console.WriteLine(m);输出的结果不改变。界面计数器一直在变。我按照你写的第二种方法,已经成功了。原因不是挂起的问题。
一年多之前 回复
hcli168
waesaeasea 第二种方法可以,非常感谢
一年多之前 回复
hcli168
waesaeasea 非常详细,但是问题没有解决,输出看的是Console.WriteLine(m);
一年多之前 回复

兄弟你这个函数名称"fuck"真牛逼,接下来说说问题,其实并不是输出数据没改变,而是你的UI线程假死掉了,没有更新这个值罢了,在你的死循环里加上Application.DoEvents()试试

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
立即提问