积极答复者
问个WP多线程调度的问题

问题
-
问个WP多线程的问题
protected override void OnBackKeyPress(CancelEventArgs e) { xBackgroundWorker.CancelAsync(); mConcelDownloadSync.WaitOne(); }
想在OnBackKeyPress事件中通知一个后台线程退出,然后等待后台线程退出完后再返回到上一页(后台线程最后会执行mConcelDownloadSync.Set()语句)
但是发现如果OnBackKeyPress方法里面的语句没有执行完并退出OnBackKeyPress方法,系统貌似永远不会去调用其他线程运行,最后我的OnBackKeyPress方法一直等待mConcelDownloadSync.Set()执行,而执行mConcelDownloadSync.Set()语句的子线程又一直等待OnBackKeyPress的退出,貌似造成了死锁
请问,有没有方法解决,谢谢
答案
-
多谢关注,已解决。
由于自己的方法调用中参数没传对,产生了逻辑错误才出现这情况。在写重现代码时才发现的,真奔溃............
问题解决了,怎么结贴呢
- 已标记为答案 Haixia_XieModerator 2012年5月14日 1:29
全部回复
-
你可以参考下文解决死锁问题:
-
这个是在页面构造函数中初始话子线程(用BackgroudWork来作为子线程)
public DownloadPage() { InitializeComponent(); //mConcelDownloadSync = new ManualResetEvent(false); xPathList = (App.Current asApp).XiaoRenShuPaths; xOfflineHelper = OfflineHelper.Instance; xCurrentImage = newBitmapImage(); xOfflineHelper.ImageSavedEvent += OnImageSaved; xOfflineHelper.DownloadXrsPicErrorEvent += OnDownloadedXrsError; xDescription = (App.Current asApp).XiaoRenShuDescription; imgPreview.Loaded += imgPreview_Loaded; xBackgroundWorker = newBackgroundWorker(); xBackgroundWorker.WorkerSupportsCancellation = true; xBackgroundWorker.DoWork += (sender, args) => xOfflineHelper.DownloadXRS(xId, xPathList, xTitle, xDescription, sender asBackgroundWorker); xOfflineHelper.DownloadedXrsFinishEvent += OnDownloadedXrsFinish; }
在DownloadXRS方法中会判断子线程是否被通知要退出(以下加粗部分为判断语句)
AutoResetEvent mPicDownloadSync = new AutoResetEvent(false); bool lSaveResult; if (!xFileStoreage.DirectoryExists(string.Concat(xXIAO_REN_SHU_DIR, "/", aId))) xFileStoreage.CreateDirectory(string.Concat(xXIAO_REN_SHU_DIR, "/", aId)); for (int i = 0; i < aPicList.Length; i++) { lSaveResult = false; if (aBackgroundWorker.CancellationPending) return false; string lDownloadPath = string.Concat(xDOMAIN, aPicList[i]); string mSavePath = string.Concat(xXIAO_REN_SHU_DIR, "/", aId, "/", lDownloadPath.Replace(xDOMAIN, "").Remove(0, 1).Replace("/", "-")); if (!xFileStoreage.FileExists(mSavePath)) { byte[] mContentArray = new byte[0]; PicDownloader.DownloadPic(lDownloadPath, e => { mContentArray = new byte[e.Length]; mContentArray = e; lSaveResult = SaveImageToDisk(aId, mSavePath, mContentArray); mPicDownloadSync.Set(); }, () => { if (DownloadXrsPicErrorEvent != null) DownloadXrsPicErrorEvent(); mPicDownloadSync.Set(); }); mPicDownloadSync.WaitOne(); } else { lSaveResult = true; if (ImageSavedEvent != null) ImageSavedEvent(mSavePath); } XElement mPicNode = new XElement("Pictures"); mPicNode.SetAttributeValue("Number", i); mPicNode.SetAttributeValue("IsDownload", lSaveResult ? 1 : 0); mPicNode.Value = aPicList[i]; aImageNode.Add(mPicNode);
页面加载完成后会直接调用启动BackgroundWorker运行,此时子线程开始运行。
void Loaded(object sender, RoutedEventArgs e) { xBackgroundWorker.RunWorkerAsync(); }
直到按下手机上的后退键通知子线程停止时,子线程再停止
protected override void OnBackKeyPress(NavigationEventArgs e) { xBackgroundWorker.CancelAsync(); }
问题就是,原本的设计之中当按下返回键之后会等待子线程退出(使用AutoResetEvent或者ManualResetEvent进行同步),然后页面再跳转的但是如果在OnBackKeyPress方法中等待的话,系统会一直停在该方法中,而子线程没有被执行。子线程没有被执行,那么子线程就不会退出,所以主线程就一直等待。
有没有方法解决这个情况?让主线程等待的同时,子线程也能够被执行
-
多谢关注,已解决。
由于自己的方法调用中参数没传对,产生了逻辑错误才出现这情况。在写重现代码时才发现的,真奔溃............
问题解决了,怎么结贴呢
- 已标记为答案 Haixia_XieModerator 2012年5月14日 1:29