代表和工人主题,第二集 [英] Delegates and Worker Threads, Episode II

查看:32
本文介绍了代表和工人主题,第二集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Re:原创帖子= Windows表格 - 如何让他们正确渲染/更新

?从8月22日开始。


好​​的我正在取得一些进展,能够使用代理在工作线程上运行

我的带壳进程。是的,我已经让它工作了,

那种 - 那就是我从UI获得了带壳的进程

线程(我想?)。但UI仍未正确更新!仍然我

表格中有白色方框,标签文字没有更新,任务栏中还有额外的

窗口。


此外,我不确定带壳应用程序本身 - 它们没有

似乎是多线程的,因为它们基本上接管了

系统 - 它根本没有响应 - 很短的时间。


无论如何,某些东西仍然阻止我的应用中的UI更新

正确。我在这里做错了什么?


以下是应用程序中的一些代码。我缩短了很多东西给

让它更具可读性......


....


//第一部分 - 声明委托

public class _SomeClass:System.Windows.Forms.Form

{

private delegate bool _CCDelegate() ;

私人代表bool _URTDelegate();


[以下其他代码...]


.. ..


//第二部分 - 实例化和调用


[...上面的其他代码]


//检查通讯

this.lblStatus.Text ="状态:检查通讯,请

等待..." ;;

_CCDelegate CCDelegate = new _CCDelegate(CC);

IAsyncResult CCResult = CCDelegate.BeginInvoke(null,null);

this.Activate(); //尝试强制表单更新

this.lblStatus.Refresh(); //尝试强制表单更新

this.Refresh(); //尝试强制表单更新

//全部或部分表单保持白色且未更新

if(!(CCDelegate.EndInvoke(CCResult)))br />
{

this.lblStatus.Text ="状态:检查失败。" ;;

Environment.Exit(-1);

}

this.lblStatus.Text ="状态:检查成功。;


//上传报告总数

this.lblStatus.Text ="状态:上传报告总数,请

等待......" ;;

_URTDelegate URTDelegate = new _URTDelegate( URT);

IAsyncResult URTResult = URTDelegate.BeginInvoke(null,null);

this.Activate(); //尝试强制表单更新

this.lblStatus.Refresh(); //尝试强制表单更新

this.Refresh(); //尝试强制表单更新

//全部或部分表单保持白色且未更新

if(!(URTDelegate.EndInvoke(URTResult)))br />
{

this.lblStatus.Text ="状态:上传报告总数失败。" ;;

Environment.Exit(-1);

}

this.lblStatus.Text ="状态:上传报告总数为

成功。;


[以下其他代码......]


....


//第三部分 - 功能


//整个函数现在应该在一个工作线程上,对吗?

//这个整个函数现在应该与UI线程分开,

对吗?

公共布尔CC()

{

试试

{

bool StatusFlag = false;


[...启动Process类任务的代码在这里...]

//小心不包含与UI的互动


返回StatusFlag;

}

catch(例外x)

{

MessageBox.Show(" FATAL ERROR - " + x.Message);

bool StatusFlag = false;

返回StatusFlag;

}

}


//整个函数现在应该在一个工作线程上,对吗?

//这个整个函数现在应该与UI线程分开,
对吧?

公共布尔URT()

{

试试

{

bool StatusFlag = false;


[...启动Process类任务的代码在这里...]

//小心不包含与UI的互动


返回StatusFlag;

}

catch(例外x)

{

MessageBox.Show(" FATAL ERROR - " + x.Message);

bool StatusFlag = false;

返回StatusFlag ;

}

}


....


现在好了我明白我在这里使用异步处理,但

我用EndInvoke阻止了......但是我必须同步完成这个东西过程

。非常重要的是,一个流程在下一个流程开始之前完成。如果有更好的方法,那么有人请

发布代码吗?


此时我只需要:


1.能够从UI线程中获取进程,以便UI

继续正确更新。


2.能够同步地运行这些过程。


我真的很感谢你们中的任何人的帮助,因为我真的想要这样做能够完成这项工作。


谢谢。

解决方案

Joey,


当你说< br>

[...启动Process类任务的代码在这里...]

你的代表中的
,你的意思是你实际上是通过System.Diagnostics.Process启动一个进程和

可能监视它?如果是这样,你可以启动一个进程,设置它的.ExitCode + = new EventHandler(CallbackFuncHere);然后

设置它的.EnableRaisingEvents = true;因此,当

进程从该回调完成(好或坏)时,您将获得一个回调,您可以链接更多

进程从新的回调处理程序开始序列化整个流程。


我的猜测是你的代表需要一些时间来执行。当你执行下面的

时:

IAsyncResult CCResult = CCDelegate.BeginInvoke(null,null);
this.Activate(); //尝试强制表单更新
this.lblStatus.Refresh(); //尝试强制表单更新
this.Refresh(); //尝试强制表单更新
//全部或部分表单保持白色而不更新
if(!(CCDelegate.EndInvoke(CCResult)))


我的理论是这些人:

this.Activate(); //尝试强制表单更新
this.lblStatus.Refresh(); //尝试强制表单更新
this.Refresh(); //尝试强制表单更新




所有通过发布到主线程的消息来做他们的魔术。但是在你放弃程序控制(到内部消息循环)之前你打了:

if(!(CCDelegate.EndInvoke(CCResult)))




哪个块...和中提琴,它就像你做了一个普通的旧调用!


如果你没有使用System.Diagnostics.Process要在代理中实际创建其他

进程,也许你应该传递BeginInvoke

" callback"代表。从这个回调中你做了相当于

非阻塞的EndInvoke()并继续发出下一个带有

新回调的BeginInvoke,依此类推,直到一切都是序列化你喜欢,但

主线程基本上都在它的消息循环中坐着!

希望这会有所帮助。


问候,

艾琳。



伙计们,我已经阅读了所有的链接。我已经尝试了建议的

选项,虽然我不确定用于实现

的代码。我已经成功创建并使用了代理(在发布的代码中显示为

)。但是,UI ***仍然没有
更新***。我已经坚持了几个月了。任何人都可以提供一个简单的解决方案吗?具体来说,

如何修改已发布的代码以使其正确更新UI?我在这里用完了两个选项......我想我不会得到它。这个

继续非常令人沮丧,但我不会给

起来......


谢谢,

JP


" Joe Mayo" < JM *** @ ddiieessppaammeerrssddiiee.com>在消息新闻中写道:< Og ************** @ TK2MSFTNGP12.phx.gbl> ...

嗨Joey,
以下是一些有关线程的文章,可以帮助您加快速度。

http://www.windowsforms.net/Default=\"d=40#Threading

记得使用Control .Invoke / BeginInvoke,用于调用更新UI的主UI
线程上的方法。此外,如果您使用BeginInvoke,请务必调用EndInvoke以避免内存泄漏。

此外,请检查使用BeginInvoke的AsyncCallback参数的异步委托模式。我可能会弄错,但我认为您的UI更新问题的一部分可能是您在与BeginInvoke相同的方法中调用EndInvoke并在主UI线程上阻塞。这里是对异步委托模式的引用:

http://msdn.microsoft.com/library/de...rnoverview.asp
<看看开始异步调用时提供回调委托的例子。


-
http://www.csharp-station.com

" Joey Powell和QUOT; <乔********* @ goldcoinc.com>在消息中写道
新闻:bd ************************* @ posting.google.co m ...

Re:原始帖子= Windows表单 - 如何让它们正确呈现/更新?从8月22日开始。

好的,我正在取得一些进展,能够使用代理在工作线程上运行我的带壳进程。是的,我已经让它工作了,
有点 - 我已经从UI
线程中获得了带壳程序(我认为?)。但UI仍未正确更新!我仍然有表格的白色框,没有更新的标签文字,以及任务栏中的额外窗口。

我也不确定带壳的应用程序本身 - 他们不要似乎是多线程的,因为它们基本上是接管的。
系统 - 它根本没有响应 - 很短的时间。

无论如何,某些东西仍然阻止我的应用程序中的UI正确更新
。世界上我在这里做错了什么?

以下是应用程序中的一些代码。我缩短了很多东西以使其更具可读性......

//

//第一部分 - 宣布代表
公开class _SomeClass:System.Windows.Forms.Form
{private delegate bool _CCDelegate();
私人代表bool _URTDelegate();

[其他代码如下。 ..]

//
//第二部分 - 实例化和调用

[...上面的其他代码]

//检查通信
this.lblStatus.Text ="状态:检查通讯,请
等待...... 
_CCDelegate CCDelegate = new _CCDelegate(CC);
IAsyncResult CCResult = CCDelegate.BeginInvoke(null,null);
this.Activate(); //尝试强制表单更新
this.lblStatus.Refresh(); //尝试强制表单更新
this.Refresh(); //尝试强制表单更新
//全部或部分表单保持白色且未更新
if(!(CCDelegate.EndInvoke(CCResult)))
{
.lblStatus.Text =" Status:Check failed。" ;;
Environment.Exit(-1);
}
this.lblStatus.Text ="状态:检查成功。 " ;;

//上传报告总数
this.lblStatus.Text ="状态:上传报告总数,请
等待......" ;;
_URTDelegate URTDelegate = new _URTDelegate(URT);
IAsyncResult URTResult = URTDelegate.BeginInvoke(null,null);
this.Activate(); //尝试强制表单更新
this.lblStatus.Refresh(); //尝试强制表单更新
this.Refresh(); //尝试强制表单更新
//全部或部分表单保持白色而不更新
if(!(URTDelegate.EndInvoke(URTResult)))
{
这个.lblStatus.Text ="状态:上传报告总数失败。;
Environment.Exit(-1);
}
this.lblStatus.Text ="状态:上传报告总数是否成功。;

[其他代码如下......]

...

//第三部分 - 函数

//整个函数现在应该在一个工作线程上,对吧?
//整个函数现在应该与UI线程分开,
对了?公共bool CC()
{
尝试
} bool StatusFlag = false;

[...启动任务的代码关于Process类到这里......]
//小心不要与UI交互

返回StatusFlag;
}
catch(异常x)
{
消息Box.Show(" FATAL ERROR - " + x.Message);
bool StatusFlag = false;
返回StatusFlag;
}
}
//整个函数现在应该在工作线程,对吧?
//整个函数现在应该与UI线程分开,对吧?
公共布尔URT()
{
尝试
{
bool StatusFlag = false;

[...在Process类上启动任务的代码在这里...]
//小心不包含与UI的交互

返回StatusFlag;
}
catch(例外x)
{MessageBox.Show(" FATAL ERROR - " + x.Message) ;
bool StatusFlag = false;
返回StatusFlag;
}
}

...

好的,现在我明白了我在这里使用异步处理,但
我用EndInvoke阻止......但是我必须同步完成这个东西的过程。一个过程在下一个过程开始之前完成是非常重要的。如果有更好的方法,那么有人会发布代码吗?

此时我需要的是:

1.关闭进程的能力UI线程,以便UI继续正确更新。

2.同步运行这些进程的能力。

我真的很感激任何来自我们中的任何人都希望能够做到这一点。

谢谢。



< blockquote>你能提供一个简短而完整的prorgram - 编译 - 然后

我会看看它(我打赌其他人也会这样)。它有点难以拼凑出小代码所发生的事情

片段(特别是当>>在每行前面时)。


请参阅Jon Skeet的简短但完整的页面:
http://www.pobox.com/~skeet/csharp/complete.html


-

Mike Mayer
http://www.mag37.com/ csharp /
mi**@mag37.com

" Joey Powell" <乔********* @ goldcoinc.com>在消息中写道

news:bd ************************** @ posting.google.c om ...

伙计们,我已经阅读了所有的链接。我已经尝试了建议的
选项,但我不确定用于实现的代码。我已经成功创建并使用了代理(如发布的代码中所示)。但是,UI ***仍然没有更新***。我已经坚持了几个月了。任何人都可以提供一个简单的解决方案来实现这项工作吗?具体来说,如何修改已发布的代码以使其正确更新UI?我在这里没有选择......我想我不会得到它。这个
仍然非常令人沮丧,但我不会给
起来......

谢谢,
JP

;乔梅奥 < JM *** @ ddiieessppaammeerrssddiiee.com>在消息中写道



news:< Og ************** @ TK2MSFTNGP12.phx.gbl> ...

Joey,

以下是一些关于线程的文章,可以帮助你达到
的速度。
http://www.windowsforms.net/Default....d = 40#线程

请记住使用Control.Invoke / BeginInvoke来调用更新UI的
主UI线程上的方法。此外,如果您使用BeginInvoke,请确保
调用EndInvoke以避免内存泄漏。

另外,请检查使用BeginInvoke的AsyncCallback参数的异步委托模式。我可能会弄错,但我认为
部分UI更新问题可能是你在与BeginInvoke相同的方法中调用EndInvoke并在主UI线程上阻塞。这里是对异步委托模式的
a参考:

http://msdn.microsoft.com/library/de...rnoverview.asp
看看在示例中说当
开始异步调用时提供回调委托。

Joe
-
http://www.csharp-station.com

" Joey Powell" <乔********* @ goldcoinc.com>在消息中写道
新闻:bd ************************* @ posting.google.co m ...

Re:原始帖子= Windows表单 - 如何让它们正确呈现/更新?从8月22日开始。

好的,我正在取得一些进展,能够使用代理在工作线程上运行我的带壳进程。是的,我已经让它工作了,
有点 - 我已经从UI
线程中获得了带壳程序(我认为?)。但UI仍未正确更新!我仍然有表格的白色框,没有更新的标签文字,以及任务栏中的额外窗口。

我也不确定带壳的应用程序本身 - 他们不要似乎是多线程的,因为它们基本上是接管的。
系统 - 它根本没有响应 - 很短的时间。

无论如何,某些东西仍然阻止我的应用程序中的UI正确更新
。世界上我在这里做错了什么?

以下是应用程序中的一些代码。我缩短了很多东西以使其更具可读性......

//

//第一部分 - 宣布代表
公开class _SomeClass:System.Windows.Forms.Form
{private delegate bool _CCDelegate();
私人代表bool _URTDelegate();

[其他代码如下。 ..]

//
//第二部分 - 实例化和调用

[...上面的其他代码]

//检查通信
this.lblStatus.Text ="状态:检查通讯,请
等待...... 
_CCDelegate CCDelegate = new _CCDelegate(CC);
IAsyncResult CCResult = CCDelegate.BeginInvoke(null,null);
this.Activate(); //尝试强制表单更新
this.lblStatus.Refresh(); //尝试强制表单更新
this.Refresh(); //尝试强制表单更新
//全部或部分表单保持白色且未更新
if(!(CCDelegate.EndInvoke(CCResult)))
{
.lblStatus.Text =" Status:Check failed。" ;;
Environment.Exit(-1);
}
this.lblStatus.Text ="状态:检查成功。 " ;;

//上传报告总数
this.lblStatus.Text ="状态:上传报告总数,请
等待......" ;;
_URTDelegate URTDelegate = new _URTDelegate(URT);
IAsyncResult URTResult = URTDelegate.BeginInvoke(null,null);
this.Activate(); //尝试强制表单更新
this.lblStatus.Refresh(); //尝试强制表单更新
this.Refresh(); //尝试强制表单更新
//全部或部分表单保持白色而不更新
if(!(URTDelegate.EndInvoke(URTResult)))
{
这个.lblStatus.Text ="状态:上传报告总数失败。;
Environment.Exit(-1);
}
this.lblStatus.Text ="状态:上传报告总数是否成功。;

[其他代码如下......]

...

//第三部分 - 函数

//整个函数现在应该在一个工作线程上,对吧?
//整个函数现在应该与UI线程分开,
对了?公共bool CC()
{
尝试
} bool StatusFlag = false;

[...启动任务的代码关于Process类到这里......]
//小心不要与UI交互

返回StatusFlag;
}
catch(异常x)
{
消息Box.Show(" FATAL ERROR - " + x.Message);
bool StatusFlag = false;
返回StatusFlag;
}
}
//整个函数现在应该在工作线程,对吧?
//整个函数现在应该与UI线程分开,对吧?
公共布尔URT()
{
尝试
{
bool StatusFlag = false;

[...在Process类上启动任务的代码在这里...]
//小心不包含与UI的交互

返回StatusFlag;
}
catch(例外x)
{MessageBox.Show(" FATAL ERROR - " + x.Message) ;
bool StatusFlag = false;
返回StatusFlag;
}
}

...

好的,现在我明白了我在这里使用异步处理,但
我用EndInvoke阻止......但是我必须同步完成这个东西的过程。一个过程在下一个过程开始之前完成是非常重要的。如果有更好的方法,那么有人会发布代码吗?

此时我需要的是:

1.关闭进程的能力UI线程,以便UI继续正确更新。

2.同步运行这些进程的能力。

我真的很感激任何来自我们中的任何人都希望能够做到这一点。

谢谢。



Re: Original post = Windows forms - how do I get them to render/update
properly? from August 22.

Okay I am making some progress with being able to use delegates to run
my shelled processes on worker threads. Yes I have gotten it to work,
kind-of - that is I have gotten the shelled processes off of the UI
thread (I think?). But the UI still is not updating properly! Still I
have white boxes for forms, label text that does not update, and extra
windows in the taskbar.

Also I am not sure about the shelled apps themselves - they do not
appear to be multi-threaded because they essentially "take over" the
system - it does not respond at all - for short periods of time.

Anyways something is still preventing the UI in my app from updating
properly. What in the world am I doing wrong here?

Below is some code from the app. I have shortened a lot of stuff to
make it more readable...

....

//part I - declare delegates
public class _SomeClass : System.Windows.Forms.Form
{
private delegate bool _CCDelegate();
private delegate bool _URTDelegate();

[other code below...]

....

//part II - instantiate and invoke

[...other code above]

//check communications
this.lblStatus.Text = "Status: Checking communications, please
wait...";
_CCDelegate CCDelegate = new _CCDelegate(CC);
IAsyncResult CCResult = CCDelegate.BeginInvoke(null, null);
this.Activate(); //try to force form to update
this.lblStatus.Refresh(); //try to force form to update
this.Refresh(); //try to force form to update
//all or part of form remains white and not updated
if(!(CCDelegate.EndInvoke(CCResult)))
{
this.lblStatus.Text = "Status: Check failed.";
Environment.Exit(-1);
}
this.lblStatus.Text = "Status: Check was successful.";

//Upload report totals
this.lblStatus.Text = "Status: Uploading report totals, please
wait...";
_URTDelegate URTDelegate = new _URTDelegate(URT);
IAsyncResult URTResult = URTDelegate.BeginInvoke(null, null);
this.Activate(); //try to force form to update
this.lblStatus.Refresh(); //try to force form to update
this.Refresh(); //try to force form to update
//all or part of form remains white and not updated
if(!(URTDelegate.EndInvoke(URTResult)))
{
this.lblStatus.Text = "Status: Upload of report totals failed.";
Environment.Exit(-1);
}
this.lblStatus.Text = "Status: Upload of report totals was
successful.";

[other code below...]

....

//part III - functions

//this entire function should now be on a worker thread, right?
//this entire function should now be separated from the UI thread,
right?
public bool CC()
{
try
{
bool StatusFlag = false;

[...code to launch task on Process class goes here...]
//careful to include no interaction with UI

return StatusFlag;
}
catch(Exception x)
{
MessageBox.Show("FATAL ERROR - " + x.Message);
bool StatusFlag = false;
return StatusFlag;
}
}

//this entire function should now be on a worker thread, right?
//this entire function should now be separated from the UI thread,
right?
public bool URT()
{
try
{
bool StatusFlag = false;

[...code to launch task on Process class goes here...]
//careful to include no interaction with UI

return StatusFlag;
}
catch(Exception x)
{
MessageBox.Show("FATAL ERROR - " + x.Message);
bool StatusFlag = false;
return StatusFlag;
}
}

....

Okay now I understand that I am using asynchonous processing here, yet
I am blocking with EndInvoke...but I have to make this stuff process
synchonously. It is very important that one process finishes before
the next one begins. If there is a better way then will someone please
post the code?

At this point all I need is:

1. The ability to get processes off of the UI thread so that the UI
continues to update properly.

2. The ability to run those processes syncronously.

I would really appreciate any help from any of you as I really want to
be able to make this work.

Thanks.

解决方案

Joey,

When you say

[...code to launch task on Process class goes here...]
in your delegates, do you mean you are actually launching a process and
perhaps monitoring it, via System.Diagnostics.Process? If so, you can start
a process, set its .ExitCode += new EventHandler(CallbackFuncHere); and then
set its .EnableRaisingEvents = true; Thus you will get a callback when the
process completes (wheter good or bad) from that callback you can chain more
process starts with new callback handlers to "serialize" the whole flow.

My guess is that your delegates take some time to execute. When you do the
following:
IAsyncResult CCResult = CCDelegate.BeginInvoke(null, null);
this.Activate(); //try to force form to update
this.lblStatus.Refresh(); //try to force form to update
this.Refresh(); //try to force form to update
//all or part of form remains white and not updated
if(!(CCDelegate.EndInvoke(CCResult)))
My theory is that these guys:

this.Activate(); //try to force form to update
this.lblStatus.Refresh(); //try to force form to update
this.Refresh(); //try to force form to update



all do their magic via a message posted to the main thread. But before you
relinquish program control (to the internal message loop) you hit:
if(!(CCDelegate.EndInvoke(CCResult)))



Which blocks... And viola, its just like you did a plain old invoke!

If you are not using System.Diagnostics.Process to actually create other
processes in the delegates, perhaps you should pass the BeginInvoke a
"callback" delegate. From within this callback you do what amounts to a
non-blocking EndInvoke() and proceed to issue the next BeginInvoke with a
new callback, and so on till everything is serialized to your liking but the
main thread is basically sitting around in its message loop!
Hope this helps.

Regards,
Erin.



Guys, I have read all of the links. I have tried the suggested
options, though I am not sure about the code one would use to
implement either. I have successfully created and used delegates (as
shown in the posted code). However, the UI ***still does not
update***. I have been stuck on this for a few months now. Can anyone
out there offer a simple solution to make this work? Specifically, how
could one modify the posted code to make it update the UI properly? I
am running out of options here...I guess I don''t "get it". This
continues to be extremely frustrating, but I am not going to give
up...

Thanks,
JP

"Joe Mayo" <jm***@ddiieessppaammeerrssddiiee.com> wrote in message news:<Og**************@TK2MSFTNGP12.phx.gbl>...

Hi Joey,

Here are some articles on threading that should help you get up to speed.

http://www.windowsforms.net/Default....d=40#Threading

Remember to use Control.Invoke/BeginInvoke, to call a method on your main UI
thread that updates your UI. Also, if you use BeginInvoke, be sure to call
EndInvoke to avoid a memory leak.

Also, check out the asynchronous delegate pattern that uses the
AsyncCallback parameter of BeginInvoke. I may be mistaken, but I think part
of your UI updating problem may be that you are calling EndInvoke in the
same method as BeginInvoke and blocking on your main UI thread. Here''s a
reference to the async delegate patterns:

http://msdn.microsoft.com/library/de...rnoverview.asp

Look at the example that says "Supply the callback delegate when beginning
the asynchronous call."

Joe
--
http://www.csharp-station.com
"Joey Powell" <jo*********@goldcoinc.com> wrote in message
news:bd*************************@posting.google.co m...

Re: Original post = Windows forms - how do I get them to render/update
properly? from August 22.

Okay I am making some progress with being able to use delegates to run
my shelled processes on worker threads. Yes I have gotten it to work,
kind-of - that is I have gotten the shelled processes off of the UI
thread (I think?). But the UI still is not updating properly! Still I
have white boxes for forms, label text that does not update, and extra
windows in the taskbar.

Also I am not sure about the shelled apps themselves - they do not
appear to be multi-threaded because they essentially "take over" the
system - it does not respond at all - for short periods of time.

Anyways something is still preventing the UI in my app from updating
properly. What in the world am I doing wrong here?

Below is some code from the app. I have shortened a lot of stuff to
make it more readable...

...

//part I - declare delegates
public class _SomeClass : System.Windows.Forms.Form
{
private delegate bool _CCDelegate();
private delegate bool _URTDelegate();

[other code below...]

...

//part II - instantiate and invoke

[...other code above]

//check communications
this.lblStatus.Text = "Status: Checking communications, please
wait...";
_CCDelegate CCDelegate = new _CCDelegate(CC);
IAsyncResult CCResult = CCDelegate.BeginInvoke(null, null);
this.Activate(); //try to force form to update
this.lblStatus.Refresh(); //try to force form to update
this.Refresh(); //try to force form to update
//all or part of form remains white and not updated
if(!(CCDelegate.EndInvoke(CCResult)))
{
this.lblStatus.Text = "Status: Check failed.";
Environment.Exit(-1);
}
this.lblStatus.Text = "Status: Check was successful.";

//Upload report totals
this.lblStatus.Text = "Status: Uploading report totals, please
wait...";
_URTDelegate URTDelegate = new _URTDelegate(URT);
IAsyncResult URTResult = URTDelegate.BeginInvoke(null, null);
this.Activate(); //try to force form to update
this.lblStatus.Refresh(); //try to force form to update
this.Refresh(); //try to force form to update
//all or part of form remains white and not updated
if(!(URTDelegate.EndInvoke(URTResult)))
{
this.lblStatus.Text = "Status: Upload of report totals failed.";
Environment.Exit(-1);
}
this.lblStatus.Text = "Status: Upload of report totals was
successful.";

[other code below...]

...

//part III - functions

//this entire function should now be on a worker thread, right?
//this entire function should now be separated from the UI thread,
right?
public bool CC()
{
try
{
bool StatusFlag = false;

[...code to launch task on Process class goes here...]
//careful to include no interaction with UI

return StatusFlag;
}
catch(Exception x)
{
MessageBox.Show("FATAL ERROR - " + x.Message);
bool StatusFlag = false;
return StatusFlag;
}
}

//this entire function should now be on a worker thread, right?
//this entire function should now be separated from the UI thread,
right?
public bool URT()
{
try
{
bool StatusFlag = false;

[...code to launch task on Process class goes here...]
//careful to include no interaction with UI

return StatusFlag;
}
catch(Exception x)
{
MessageBox.Show("FATAL ERROR - " + x.Message);
bool StatusFlag = false;
return StatusFlag;
}
}

...

Okay now I understand that I am using asynchonous processing here, yet
I am blocking with EndInvoke...but I have to make this stuff process
synchonously. It is very important that one process finishes before
the next one begins. If there is a better way then will someone please
post the code?

At this point all I need is:

1. The ability to get processes off of the UI thread so that the UI
continues to update properly.

2. The ability to run those processes syncronously.

I would really appreciate any help from any of you as I really want to
be able to make this work.

Thanks.



Can you provide a short and complete prorgram - that compiles - and then
I''ll have a look at it (and I''m bet some other people will as well). It''s
sometimes hard to piece together exactly what is happenning form small code
fragments (especially when >> is in front of every line).

See Jon Skeet''s page on short but complete:
http://www.pobox.com/~skeet/csharp/complete.html

--
Mike Mayer
http://www.mag37.com/csharp/
mi**@mag37.com
"Joey Powell" <jo*********@goldcoinc.com> wrote in message
news:bd**************************@posting.google.c om...

Guys, I have read all of the links. I have tried the suggested
options, though I am not sure about the code one would use to
implement either. I have successfully created and used delegates (as
shown in the posted code). However, the UI ***still does not
update***. I have been stuck on this for a few months now. Can anyone
out there offer a simple solution to make this work? Specifically, how
could one modify the posted code to make it update the UI properly? I
am running out of options here...I guess I don''t "get it". This
continues to be extremely frustrating, but I am not going to give
up...

Thanks,
JP

"Joe Mayo" <jm***@ddiieessppaammeerrssddiiee.com> wrote in message


news:<Og**************@TK2MSFTNGP12.phx.gbl>...

Hi Joey,

Here are some articles on threading that should help you get up to speed.
http://www.windowsforms.net/Default....d=40#Threading

Remember to use Control.Invoke/BeginInvoke, to call a method on your main UI thread that updates your UI. Also, if you use BeginInvoke, be sure to call EndInvoke to avoid a memory leak.

Also, check out the asynchronous delegate pattern that uses the
AsyncCallback parameter of BeginInvoke. I may be mistaken, but I think part of your UI updating problem may be that you are calling EndInvoke in the
same method as BeginInvoke and blocking on your main UI thread. Here''s a reference to the async delegate patterns:

http://msdn.microsoft.com/library/de...rnoverview.asp
Look at the example that says "Supply the callback delegate when beginning the asynchronous call."

Joe
--
http://www.csharp-station.com
"Joey Powell" <jo*********@goldcoinc.com> wrote in message
news:bd*************************@posting.google.co m...

Re: Original post = Windows forms - how do I get them to render/update
properly? from August 22.

Okay I am making some progress with being able to use delegates to run
my shelled processes on worker threads. Yes I have gotten it to work,
kind-of - that is I have gotten the shelled processes off of the UI
thread (I think?). But the UI still is not updating properly! Still I
have white boxes for forms, label text that does not update, and extra
windows in the taskbar.

Also I am not sure about the shelled apps themselves - they do not
appear to be multi-threaded because they essentially "take over" the
system - it does not respond at all - for short periods of time.

Anyways something is still preventing the UI in my app from updating
properly. What in the world am I doing wrong here?

Below is some code from the app. I have shortened a lot of stuff to
make it more readable...

...

//part I - declare delegates
public class _SomeClass : System.Windows.Forms.Form
{
private delegate bool _CCDelegate();
private delegate bool _URTDelegate();

[other code below...]

...

//part II - instantiate and invoke

[...other code above]

//check communications
this.lblStatus.Text = "Status: Checking communications, please
wait...";
_CCDelegate CCDelegate = new _CCDelegate(CC);
IAsyncResult CCResult = CCDelegate.BeginInvoke(null, null);
this.Activate(); //try to force form to update
this.lblStatus.Refresh(); //try to force form to update
this.Refresh(); //try to force form to update
//all or part of form remains white and not updated
if(!(CCDelegate.EndInvoke(CCResult)))
{
this.lblStatus.Text = "Status: Check failed.";
Environment.Exit(-1);
}
this.lblStatus.Text = "Status: Check was successful.";

//Upload report totals
this.lblStatus.Text = "Status: Uploading report totals, please
wait...";
_URTDelegate URTDelegate = new _URTDelegate(URT);
IAsyncResult URTResult = URTDelegate.BeginInvoke(null, null);
this.Activate(); //try to force form to update
this.lblStatus.Refresh(); //try to force form to update
this.Refresh(); //try to force form to update
//all or part of form remains white and not updated
if(!(URTDelegate.EndInvoke(URTResult)))
{
this.lblStatus.Text = "Status: Upload of report totals failed.";
Environment.Exit(-1);
}
this.lblStatus.Text = "Status: Upload of report totals was
successful.";

[other code below...]

...

//part III - functions

//this entire function should now be on a worker thread, right?
//this entire function should now be separated from the UI thread,
right?
public bool CC()
{
try
{
bool StatusFlag = false;

[...code to launch task on Process class goes here...]
//careful to include no interaction with UI

return StatusFlag;
}
catch(Exception x)
{
MessageBox.Show("FATAL ERROR - " + x.Message);
bool StatusFlag = false;
return StatusFlag;
}
}

//this entire function should now be on a worker thread, right?
//this entire function should now be separated from the UI thread,
right?
public bool URT()
{
try
{
bool StatusFlag = false;

[...code to launch task on Process class goes here...]
//careful to include no interaction with UI

return StatusFlag;
}
catch(Exception x)
{
MessageBox.Show("FATAL ERROR - " + x.Message);
bool StatusFlag = false;
return StatusFlag;
}
}

...

Okay now I understand that I am using asynchonous processing here, yet
I am blocking with EndInvoke...but I have to make this stuff process
synchonously. It is very important that one process finishes before
the next one begins. If there is a better way then will someone please
post the code?

At this point all I need is:

1. The ability to get processes off of the UI thread so that the UI
continues to update properly.

2. The ability to run those processes syncronously.

I would really appreciate any help from any of you as I really want to
be able to make this work.

Thanks.



这篇关于代表和工人主题,第二集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆