我有一个异步运行的Windows svc(我编辑了方法及其参数以使它们异步),有点像:http://msdn.microsoft.com/en-us/library/ms731177.aspx
但是,我调用我想异步运行的任务(对服务/服务器的调用),然后更新UI(使用后台工作者的ReportProgress() - 所有这些都发生在dowork()方法中背景工作者)。但是,我调用Endxxx方法来获得结果,但问题是,我的代码不应该是这样吗?
while (!asyncresult.IsCompleted) { // Do all UI updating etc here... }
// Call endXXX here.
但是,这种方法会锁定UI。目前,我的代码是这样的(并没有锁定UI):
IAsyncResult res = null;
try
{
res = serviceX.BeginXXX(ResultCallBack, "");
}
catch (FaultException<ManagementException> managementEx)
{
Logger.Error(managementEx.Detail.ToString());
MessageBox.Show("Could not add printer. See log.");
}
InstallBackgoundWorker.ReportProgress(90);
InstallBackgoundWorker.ReportProgress(91);
InstallBackgoundWorker.ReportProgress(93);
InstallBackgoundWorker.ReportProgress(94);
InstallBackgoundWorker.ReportProgress(95);
InstallBackgoundWorker.ReportProgress(96);
InstallBackgoundWorker.ReportProgress(97);
if (res.IsCompleted)
{
ResultCallBack(res);
}
InstallBackgoundWorker.ReportProgress(100);
这是对的吗?这对我来说似乎不对。
答案 0 :(得分:0)
不,你不应该采取第一种方法,因为它违背了以异步方式调用方法的目标。
自
以来,第二种方法也很麻烦除非异步提供异步作业,否则无法显示异步作业的进度报告。
解决方案是:
您还必须了解从后台线程与UI线程进行通信的问题,并在Windows窗体中使用Invoke并在WPF中使用Dispatcher。
答案 1 :(得分:0)
我不确定您是否正确使用了异步模式。看起来应该是这样的:
void Start()
{
System.IO.Stream s = ...;
byte[] buf = ...;
// start the IO.
s.BeginRead(buf, 0, buf.Length, res =>
{
// this gets called when it's finished,
// but you're in a different thread.
int len = s.EndRead(res);
// so you must call Dispatcher.Invoke
// to get back to the UI thread.
Dispatcher.Invoke((Action)delegate
{
// perform UI updates here.
});
}, null);
// the IO is started (and maybe finished) here,
// but you probably don't need to put anything here.
}
用Stream
写,因为我不知道你的对象的签名,但希望你明白了!您需要在调用Begin方法后直接在回调中处理完成操作, not 。您不应该轮询IsCompleted
属性。