我正在尝试使用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
如果我想在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) 现在我知道属性不支持异步/等待有充分理由.但有时您需要从属性设置器中启动一些额外的后台处理 - 一个很好的例子是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应用程序中,大量使用数据绑定似乎很常见.
试图await
在LINQ
查询中使用关键字,我得到这个:
'await'运算符只能用在初始'from'子句的第一个集合表达式中的查询表达式中,或者用在'join'子句的集合表达式中
示例代码:
var data = (from id in ids
let d = await LoadDataAsync(id)
select d);
Run Code Online (Sandbox Code Playgroud)
是不可能等待LINQ
查询中的某些内容,还是需要以不同的方式构建它?
我正在开发Windows应用商店应用程序(Windows 8).
我需要根据存储在应用程序数据中的数据和地址发送电子邮件,而无需用户输入数据或地址.
实现它的正确/简单方法是什么?
EitanB
在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.
求助,见答案;
我正在开发一个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) 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操作不应该放在自己的线程中.
推荐的方法是什么?
我们正在尝试在我们的客户端中使用用户确定(在设置屏幕上)可选的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
标头,并且似乎没有任何方式来访问或更改它传递给构造函数后.此外,如果对象的头部定义,则更改对象的头部对请求的头部没有任何影响.HttpClientHandler
HttpClient
HttpRequestMessage
HttpClientHandler
是否有任何方法可以在不重新创建HttpClient
每次更改的情况下执行此操作?
编辑:我也试着修改为基准HttpClientHandler
来改变AutomaticDecompression
在运行,但是这是引发此异常:
此实例已启动一个或多个请求.只能在发送第一个请求之前修改属性.
在WinRT中没有FileInfo
类,只有一个StorageFile
类.
如何使用StorageFile
该类获取文件的大小?
winrt-async ×10
c# ×6
async-await ×4
c#-5.0 ×3
windows-8 ×2
.net ×1
.net-4.5 ×1
exception ×1
filesize ×1
gzip ×1
json.net ×1
linq ×1
mvvm ×1
winrt-xaml ×1