0

所以我有一个特殊的问题。我有一组这样的方法:

StorageFile file;
public void WriteStuff() //This implements an interface, so can't be changed to async with a task returned
{
    Write();
}
async void Write()
{
  await FileIO.AppendTextAsync(file, DateTime.Now + " testing!"+Environment.NewLine);
}
async void Create()
{
  file=await ApplicationData.Current.LocalFolder.CreateFileAsync("test.txt", CreationCollisionOptions.OpenIfExists);
}

然后像这样实际使用它的代码:

var x=new Foo();
for(int i=0;i<1000;i++)
{
  x.WriteStuff(); //can't use async/await from here. This is in a portable class library
}

每当我打电话Test时,我都会收到非常随机的错误。FileNotFound、AccessDenied、AccessViolation 等。

它似乎只在AppendTextAsync异步调用多次时发生。我会想象一个异步 API 会......好吧,线程安全,但显然不是。这是真的?

另外,如何在不修改调用代码的情况下解决此问题?

4

1 回答 1

1

如果你真的需要这样做,那么你唯一的选择是同步Wait()地让异步方法完成(或使用Result):

void Write()
{
    FileIO.AppendTextAsync(
        file, DateTime.Now + " testing!"+Environment.NewLine).Wait();
}

void Create()
{
    file = ApplicationData.Current.LocalFolder.CreateFileAsync(
        "test.txt", CreationCollisionOptions.OpenIfExists).Result;
}

但这违背了异步代码的全部目的,所以你真的应该避免这样做。此外,如果您调用的代码没有正确编写,这样做会导致死锁。

不能从这里使用 async/await。这是在一个可移植的类库中

可以使用async-await来自 PCL。如果您的平台本身不支持它,您只需要定位支持它的平台并可能还引用 Microsoft.Bcl.Async。

于 2013-06-12T14:53:58.690 回答