Windows 8.1 开发过程中遇到的小问题(2)

本文详细介绍了在Windows 8.1应用中实现分享功能时遇到的死锁问题及其解决方案。通过调整代码使其支持异步操作,避免了线程间的死锁现象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

又是在Windows 8.1 的分享功能,再次出现错误:

A COM call (IID: ***, method index: *) to an ASTA (thread *) was blocked because the call chain originated in or passed through another ASTA (thread *). This call pattern is deadlock-prone and disallowed by apartment call control.

Additional information: A COM call to an ASTA was blocked because the call chain originated in or passed through another ASTA. This call pattern is deadlock-prone and disallowed by apartment call control.

A COM call (IID: {*}, method index: *) to an ASTA (thread *) was blocked because the call chain originated in or passed through another ASTA (thread *). This call pattern is deadlock-prone and disallowed by apartment call control.

 

问题代码,红色部分是错误源:(作为分享目标应用,接受分享进来的文件的代码:例如,用photo应用分享图片)

else if (containsStorageFileFormat)
            {
                try
                {
                    var items = await operation.Data.GetStorageItemsAsync();
                    Windows.Storage.StorageFile sf = items[0] as Windows.Storage.StorageFile;
                    if (sf.FileType == ".jpg" || sf.FileType == ".png" || sf.FileType == ".gif")
                    {
                        using (IRandomAccessStreamWithContentType ras = await sf.OpenReadAsync())
                        {                            
                            ras.Seek(0);
                            if (vm.UploadImage == null)
                                vm.UploadImage = new BitmapImage();
                            vm.UploadImage.SetSource(ras);
                            using (System.IO.Stream stream = ras.AsStreamForRead())
                            {
                                stream.Seek(0, SeekOrigin.Begin);
                                using (System.IO.MemoryStream memStream = new System.IO.MemoryStream())
                                {
                                    stream.CopyTo(memStream);
                                    memStream.Position = 0;

                                    vm.SetImageRelative(memStream, "ShareImage.jpg", ras.ContentType, true);
                                }
                            }
                        }
                    }
                }
                catch (Exception e2)
                {
                    WeiboForWin8.Tools.MainProjectTool.HandleException(e2, "ShareTargetView.OnNavigatedTo_2");
                    vm.UploadImage = null;
                }
            }

以下是来自http://www.tuicool.com/articles/Rjmeay 帖子中对ASTA 和 STA 的描述,

 “Application Single Threaded Apartment” (ASTA).

MSDN Reference on Application Single Threaded Apartments

Which, essentially says that an ASTA is an STA that you can’t create yourself and which doesn’t allow re-entrancy.

 

也就是说,线程访问出现了问题,后把此行代码改为异步调用:

else if (containsStorageFileFormat)
            {
                try
                {
                    var items = await operation.Data.GetStorageItemsAsync();
                    Windows.Storage.StorageFile sf = items[0] as Windows.Storage.StorageFile;
                    if (sf.FileType == ".jpg" || sf.FileType == ".png" || sf.FileType == ".gif")
                    {
                        IRandomAccessStreamWithContentType ras = null;
                        await Task.Run(async() =>
                        {
                            ras = await sf.OpenReadAsync();                            
                        });
                        if (ras != null) { 
                                ras.Seek(0);
                                if (vm.UploadImage == null)
                                    vm.UploadImage = new BitmapImage();
                                vm.UploadImage.SetSource(ras);
                                using (System.IO.Stream stream = ras.AsStreamForRead())
                                {
                                    stream.Seek(0, SeekOrigin.Begin);
                                    using (System.IO.MemoryStream memStream = new System.IO.MemoryStream())
                                    {
                                        stream.CopyTo(memStream);
                                        memStream.Position = 0;

                                        vm.SetImageRelative(memStream, "ShareImage.jpg", ras.ContentType, true);
                                    }
                                }
                        }
                    }
                }
                catch (Exception e2)
                {
                    WeiboForWin8.Tools.MainProjectTool.HandleException(e2, "ShareTargetView.OnNavigatedTo_2");
                    vm.UploadImage = null;
                }
            }

大功告成。

 

我在做share target的功能的时候,发现很多问题,比如:应用程序未启动或被结束进程时,分享中的某些方法调用正常,但程序在进程中时会发生异常,反之也会有异常,可能是某些方法调用的机制不同(未启动时只能通过COM?),因此,大家一定要在做此功能的时候注意代码的调式和错误处理,尽管很繁琐(调式share简直就是一种煎熬)

转载于:https://www.cnblogs.com/lihaiyin/p/3457164.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值