标签: winrt-async

在意外的时间调用了一个方法

我正在尝试使用GetFilesAsync迭代目录中的所有文件,但每次调用GetResults方法时,它都会抛出一个异常

System.InvalidOperationException:在意外时间调用了一个方法

代码很简单

var files = myStorageFolder.GetFilesAsync(); //runs fine
var results = files.GetResults(); //throws the exception
Run Code Online (Sandbox Code Playgroud)

我是Win 8 dev的新手,所以我可能会遗漏一些明显的东西.

编辑(已解决) 我正在运行我的控制台应用程序,但现在该程序运行异步,该files.GetResult()方法不再存在.

static void Main(string[] args)
{
   var files = GetFiles(myStorageFolder);
   var results = files.GetAwaiter().GetResults();//Need to add GetAwaiter()
}

static async Task GetFiles(StorageFolder sf)
{
   await sf.GetFilesAsync();
}
Run Code Online (Sandbox Code Playgroud)

exception local-storage windows-8 windows-runtime winrt-async

23
推荐指数
2
解决办法
2万
查看次数

IValueConverter的异步实现

如果我想在IValueConverter中触发一个异步方法.

有没有更好的等待,然后通过调用结果属性强制它同步?

public async Task<object> Convert(object value, Type targetType, object parameter, string language)
{
    StorageFile file = value as StorageFile;

    if (file != null)
    {
        var image = ImageEx.ImageFromFile(file).Result;
        return image;
    }
    else
    {
        throw new InvalidOperationException("invalid parameter");
    }
}
Run Code Online (Sandbox Code Playgroud)

c# async-await c#-5.0 windows-runtime winrt-async

23
推荐指数
1
解决办法
1万
查看次数

从数据绑定属性设置器中调用异步方法的正确方法?

现在我知道属性不支持异步/等待有充分理由.但有时您需要从属性设置器中启动一些额外的后台处理 - 一个很好的例子是MVVM场景中的数据绑定.

在我的例子中,我有一个绑定到ListView的SelectedItem的属性.当然,我立即将新值设置为支持字段,并完成属性的主要工作.但是,UI中所选项目的更改还需要触发REST服务调用,以根据现在选择的项目获取一些新数据.

所以我需要调用异步方法.显然,我无法等待它,但我也不想激活并忘记呼叫,因为在异步处理期间我可能会错过异常.

现在我的看法如下:

private Feed selectedFeed;
public Feed SelectedFeed
{
    get
    {
        return this.selectedFeed;
    }
    set
    {
        if (this.selectedFeed != value)
        {
            this.selectedFeed = value;
            RaisePropertyChanged();

            Task task = GetFeedArticles(value.Id);

            task.ContinueWith(t =>
                {
                    if (t.Status != TaskStatus.RanToCompletion)
                    {
                        MessengerInstance.Send<string>("Error description", "DisplayErrorNotification");
                    }
                });
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

好的,除了事实上我可以将处理从setter转移到同步方法,这是处理这种情况的正确方法吗?有没有更好,更简洁的解决方案,我没有看到?

会非常有兴趣看到其他一些问题.我有点好奇,我无法找到关于这个具体主题的任何其他讨论,因为在MVVM应用程序中,大量使用数据绑定似乎很常见.

mvvm async-await windows-runtime winrt-async

21
推荐指数
1
解决办法
3062
查看次数

如何等待Linq查询中的方法

试图awaitLINQ查询中使用关键字,我得到这个:

'await'运算符只能用在初始'from'子句的第一个集合表达式中的查询表达式中,或者用在'join'子句的集合表达式中

示例代码:

var data = (from id in ids
            let d = await LoadDataAsync(id)
            select d);
Run Code Online (Sandbox Code Playgroud)

是不可能等待LINQ查询中的某些内容,还是需要以不同的方式构建它?

linq async-await c#-5.0 windows-runtime winrt-async

16
推荐指数
1
解决办法
1万
查看次数

如何从WinRT/Windows应用商店应用程序发送电子邮件?

我正在开发Windows应用商店应用程序(Windows 8).

我需要根据存储在应用程序数据中的数据和地址发送电子邮件,而无需用户输入数据或地址.

实现它的正确/简单方法是什么?

EitanB

c# windows-8 windows-runtime winrt-xaml winrt-async

12
推荐指数
3
解决办法
2万
查看次数

如何等待IAsyncAction?

在Windows应用商店应用中,C++(C#虽然类似),做类似的事情

IAsyncAction^ Action = CurrentAppSimulator::ReloadSimulatorAsync(proxyFile);
create_task( Action ).then([this]()
{
}.wait();
Run Code Online (Sandbox Code Playgroud)

导致未处理的异常.通常是

Microsoft C++ exception: Concurrency::invalid_operation at memory location 0x0531eb58
Run Code Online (Sandbox Code Playgroud)

在尝试使用它之前,我需要完成该操作以获取我的In App Purchase信息.这里奇怪的是除了IAsyncAction之外的任何其他东西都等待.IAsyncOperation和IAsyncOperationWithProgress工作正常,但是这个?异常然后崩溃.

说实话,我不知道IAsyncOperation和IAsyncAction之间有什么区别,它们看起来和我类似.

更新:

通过分析此页面http://msdn.microsoft.com/en-us/library/vstudio/hh750082.aspx,您可以发现IAsyncAction只是一个没有返回类型的IAsyncOperation.但是,您可以看到大多数IAsyncAction-s都是可以等待的.但真正的问题是某些Windows函数只是想在特定线程上执行(出于某种原因).ReloadSimulatorAsync就是一个很好的例子.

使用这样的代码:

void WaitForAsync( IAsyncAction ^A )
{   
    while(A->Status == AsyncStatus::Started)
    {
        std::chrono::milliseconds milis( 1 );
        std::this_thread::sleep_for( milis );
    }   
    AsyncStatus S = A->Status;  
}
Run Code Online (Sandbox Code Playgroud)

导致无限循环.如果调用其他功能,它实际上是有效的.这里的问题是,如果一切都是异步,为什么需要在特定线程上执行任务?它应该是RunOn(Main/UI)Thread或类似的而不是Async.

求助,见答案;

windows-runtime winrt-async

11
推荐指数
2
解决办法
1万
查看次数

为什么在循环中使用StreamSocket会导致内存泄漏?

我正在开发一个C#,UWP 10解决方案,它使用快速,连续的读/写循环与网络设备进行通信.API提供的StreamSocket似乎工作得很好,直到我意识到存在内存泄漏:Task<uint32>堆中有一个累积,大约每分钟数百个.

无论我while (true)在内部使用普通旧循环async Task,还是使用ActionBlock<T>TPL Dataflow 自我发布(根据此答案),结果都是相同的.

如果我从套接字中消除读取并专注于写作,我能够进一步隔离问题:无论是使用DataWriter.StoreAsync方法还是更直接StreamSocket.OutputStream.WriteAsync(IBuffer buffer),问题依然存在.此外,添加.AsTask()到这些没有区别.

即使垃圾收集器运行,它们Task<uint32>也永远不会从堆中删除.所有这些任务都是完整的(RanToCompletion),没有任何错误或任何其他属性值,表明"还没有准备好回收".

这个页面上似乎有一个提示我的问题(从托管到非托管世界的字节数组阻止了内存的释放),但是规定的解决方案看起来非常明显:唯一的方法是编写所有通信逻辑C++/CX.我希望这不是真的; 当然,其他C#开发人员已经成功实现了连续的高速网络通信而没有内存泄漏.当然,微软不会发布一个只在C++/CX中没有内存泄漏的API

编辑

根据要求,一些示例代码.我自己的代码有太多层,但使用此Microsoft示例可以观察到一个更简单的示例.我做了一个简单的修改,在循环中发送1000次以突出显示问题.这是相关代码:

public sealed partial class Scenario3 : Page
{
    // some code omitted

    private async void SendHello_Click(object sender, RoutedEventArgs e)
    {
        // some code omitted

        StreamSocket socket = //get global object; socket is already connected

        DataWriter writer = new …
Run Code Online (Sandbox Code Playgroud)

.net c# stream-socket-client async-await winrt-async

10
推荐指数
1
解决办法
644
查看次数

写入文件时Json.net异步

Json.net具有将对象转换为json的异步函数,如:

jsn = await JsonConvert.DeserializeObjectAsync<T>
Run Code Online (Sandbox Code Playgroud)

但是当我想将对象写入json文件时,我最好直接使用文件Stream.

所以我认为它应该是这样的:

 var fileStream = await file.OpenAsync(FileAccessMode.ReadWrite);

    using (IOutputStream outputStream = fileStream.GetOutputStreamAt(0))
    {
        using (StreamWriter sw = new StreamWriter(fileStream.AsStreamForWrite()))
        {
            using (JsonWriter jw = new JsonTextWriter(sw))
            {
                jw.Formatting = Formatting.Indented;

                JsonSerializer serializer = new JsonSerializer();
                serializer.Serialize(jw, obj);
            }
        }
Run Code Online (Sandbox Code Playgroud)

但是在JsonSerzializer对象上我找不到异步方法.另外我认为IO操作不应该放在自己的线程中.

推荐的方法是什么?

c# json.net c#-5.0 windows-runtime winrt-async

9
推荐指数
2
解决办法
5169
查看次数

HttpClient:在运行时有条件地设置AcceptEncoding压缩

我们正在尝试在我们的客户端中使用用户确定(在设置屏幕上)可选的gzip压缩HttpClient,因此我们可以在一段时间内记录和比较多个不同呼叫的性能.我们的第一次尝试是简单地有条件地添加标题如下:

HttpRequestMessage request = new HttpRequestMessage(Method, Uri);
if (AcceptGzipEncoding)
{
     _client.DefaultRequestHeaders.AcceptEncoding.Add(new System.Net.Http.Headers.StringWithQualityHeaderValue("gzip"));
}

//Send to the server
result = await _client.SendAsync(request);

//Read the content of the result response from the server
content = await result.Content.ReadAsStringAsync();
Run Code Online (Sandbox Code Playgroud)

这创建了正确的请求,但是gzipped响应在返回时没有解压缩,导致响应乱码.我发现我们必须HttpClientHandler在构建时包括HttpClient:

HttpClient _client = new HttpClient(new HttpClientHandler
    { 
        AutomaticDecompression = DecompressionMethods.GZip
    });
Run Code Online (Sandbox Code Playgroud)

这一切都运行良好,但我们想要更改客户端是否在运行时发送Accept-Encoding: gzip标头,并且似乎没有任何方式来访问或更改它传递给构造函数后.此外,如果对象的头部定义,则更改对象的头部对请求的头部没有任何影响.HttpClientHandlerHttpClientHttpRequestMessageHttpClientHandler

是否有任何方法可以在不重新创建HttpClient每次更改的情况下执行此操作?

编辑:我也试着修改为基准HttpClientHandler来改变AutomaticDecompression在运行,但是这是引发此异常:

此实例已启动一个或多个请求.只能在发送第一个请求之前修改属性.

c# gzip .net-4.5 dotnet-httpclient winrt-async

9
推荐指数
3
解决办法
2万
查看次数

如何在WinRT中获取文件大小?

在WinRT中没有FileInfo类,只有一个StorageFile类.

如何使用StorageFile该类获取文件的大小?

c# filesize winrt-async

8
推荐指数
2
解决办法
6363
查看次数