步骤是这样的。
点击一个按钮然后开始异步委托执行一个循环。
在循环中会访问到界面中的控件,由于是不同线程,需要唤起ui线程。public void SetValueFun(string str, string controlid, object form1)
{
Form1 f1 = form1 as Form1;
if (this.InvokeRequired)
{
f1.Invoke(new SetValue(SetValueFun), str, controlid, form1);
}
else
{
f1.Controls[controlid].Text = str;
}
}然后会抱无法访问已释放的对象。对象名:“Form1”。
该怎么解决?知道问题出在哪,是因为窗体关闭了,但还是在继续执行。
试过了
if(f1.isDisposed)
return;
还是不行。
点击一个按钮然后开始异步委托执行一个循环。
在循环中会访问到界面中的控件,由于是不同线程,需要唤起ui线程。public void SetValueFun(string str, string controlid, object form1)
{
Form1 f1 = form1 as Form1;
if (this.InvokeRequired)
{
f1.Invoke(new SetValue(SetValueFun), str, controlid, form1);
}
else
{
f1.Controls[controlid].Text = str;
}
}然后会抱无法访问已释放的对象。对象名:“Form1”。
该怎么解决?知道问题出在哪,是因为窗体关闭了,但还是在继续执行。
试过了
if(f1.isDisposed)
return;
还是不行。
解决方案 »
- 在局域网中的某台机器上,如何获取该局域网中其它机器的信息?
- 问一个关于内存分配的问题~~~~~~~~~~~~~
- 那位做过类似金蝶kis样子的导航菜单
- 从wrox网站下载的C#入门经典第三版的代码,很多有Application.EnableRTLMirroring();都报错,不知道是什么原因?
- 20分求vs2005的msdn
- 取字符串
- WinForm,如何显示数据库中的二进制文件
- 不用treeview 怎么显示部门的所属关系?
- c#如何打开文件对话框
- 怎样用正则表达式匹配Html Tag?
- System::Collections::ArrayList 类的深层拷贝和浅层拷贝. 求指导.
- 一道简单的编程题
AsyncCallback callBack = new AsyncCallback(FunKidsCallBack);
funkids.BeginInvoke(star, true, true, callBack, "处理结束");我这里有用了异步,GetNext这个方法是一form循环。
循环处理的结果然后显示在控件上,由于和ui不同线程,所以需要Invoke唤起ui线程显示到ui界面中的控件上。
然后如果还没循环完就关闭窗体就抱了刚才那个错。
{
Form1 f1 = form1 as Form1;
if (f1.InvokeRequired)
{
f1.Invoke(new SetValue(SetValueFun), str, controlid, form1);
}
else
{
f1.Controls[controlid].Text = str;
}
}
if(f1!=null&&!f1.IsDisposed)
{
if (f1.InvokeRequired)
{
f1.Invoke(new SetValue(SetValueFun), str, controlid, form1);
}
else
{
f1.Controls[controlid].Text = str;
}
}
{
if (f1.InvokeRequired)
{
f1.Invoke(new SetValue(SetValueFun), str, controlid, form1);
}
else
{
f1.Controls[controlid].Text = str;
}
}
SetValueFun(result, "txt_Content", this);
如果上面的不行,就把flag定义成静态的
http://www.cnblogs.com/yibinboy/archive/2009/12/26/1633066.html
然后改成f1的。
{
public Form1()
{
InitializeComponent();
}
public delegate void FunDelegate();
public delegate void SetValue(int i);
private void button1_Click(object sender, EventArgs e)
{
FunDelegate fundelegate = new FunDelegate(FunProc);
AsyncCallback callback = new AsyncCallback(CallBack);
IAsyncResult result = fundelegate.BeginInvoke(callback, "处理结束");
}
public void CallBack(IAsyncResult result)
{
MessageBox.Show(result.AsyncState.ToString());
}
public void SetListBox(int i)
{
if (this != null && !this.IsDisposed)
{
if (this.InvokeRequired)
{
this.Invoke(new SetValue(SetListBox), i);
}
else
{
listBox1.Items.Add(i);
}
}
}
public void FunProc()
{
for (int i = 0; i < 10000; i++)
{
SetListBox(i);
Thread.Sleep(100);
}
}
}
这句话去掉,会引起阻塞。
Thread.Sleep(100);这两句换下位置Thread.Sleep(5000);
SetListBox(i);窗体展示后 马上关闭。然后断点点在这句上 if (this != null && !this.IsDisposed)
因为一展开窗体,就关闭,就不执行里面的代码。
而一展开,按下按钮,就只有等执行完了后才能按关闭的X按钮。
我改成这样
Thread.Sleep(5000);
SetListBox(i);
然后一按下按钮,就关闭窗体,然后断点在
if (this != null && !this.IsDisposed)
这句
没进断点里额。
不知道非哥是不是叫我这样做。
我发现了点。
如果把 this.Invoke(new SetValue(SetListBox), i);
改为
this.BeginInvoke(new SetValue(SetListBox), i);
就不会抱错。正常关闭。
只是不知道其中是什么原因。
SetListBox(i);这个方法额。断点在if (this != null && !this.IsDisposed)这句没反映。
改为
this.BeginInvoke(new SetValue(SetListBox), i);
就不会抱错。正常关闭。
只是不知道其中是什么原因。
----------------------------------------------
刚看了下,差异在if (!synchronous)
{
return entry;
}
if (!entry.IsCompleted)
{
this.WaitForWaitHandle(entry.AsyncWaitHandle);
}
if (entry.exception != null)
{
throw entry.exception;
}
return entry.retVal;Invoke 时synchronous 为true
BeginInvoke 时 synchronous 为false就是说BeginInvoke 没有处理异常,所以没有报错。
private object MarshaledInvoke(Control caller, Delegate method, object[] args, bool synchronous)反编译查看。