Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 一个任务对多个调用抛出AggregateException_C#_Exception_Windows 8_Task_Async Await - Fatal编程技术网

C# 一个任务对多个调用抛出AggregateException

C# 一个任务对多个调用抛出AggregateException,c#,exception,windows-8,task,async-await,C#,Exception,Windows 8,Task,Async Await,我的问题是,当用户单击按钮时,会调用SpeicherUser()。它通过异步使用XMLSerialization创建xml文件。因此,当用户一直快速单击按钮时,任务会被反复调用,如果任务没有完成(创建新的xml文件),则会弹出AggregateException 代码如下: public class UserList { private static List<User> _personen = new List<User>(); public List&

我的问题是,当用户单击按钮时,会调用SpeicherUser()。它通过异步使用XMLSerialization创建xml文件。因此,当用户一直快速单击按钮时,任务会被反复调用,如果任务没有完成(创建新的xml文件),则会弹出AggregateException

代码如下:

public class UserList
{
    private static List<User> _personen = new List<User>();
    public List<User> Personen
    {
        get { return _personen; }
        set { _personen = value; }
    }

    public static StorageFile file { get; set; }

    private const string filename = "Personen.xml";

    public UserList()
    {
        md.Title = "Fehler beim Speichern";
        Personen = new List<User>()
        {
            new User(){ID = 1, 
                Name = "TestUser1"},
            new User(){ID = 2, 
                Name = "TestUser2"}
        };
    }

    public async Task SpeicherUser()
    {
            await Save<UserList>();
    }

    static async public Task Save<T>()
    {
        if (await DoesFileExistAsync(filename))
        {
            //AggregatException pops up here: UserList.SaveAsync<T>().Wait()
            await Windows.System.Threading.ThreadPool.RunAsync((sender) => UserList.SaveAsync<T>().Wait(), Windows.System.Threading.WorkItemPriority.Normal);
        }
        else
        {
            file = await ApplicationData.Current.LocalFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
        }
    }

    static async Task<bool> DoesFileExistAsync(string fileName)
    {
        try
        {
            await ApplicationData.Current.LocalFolder.GetFileAsync(fileName);
            return true;
        }
        catch
        {
            return false;
        }
    }

    static async private Task SaveAsync<T>()
    {
        StorageFile sessionFile = await ApplicationData.Current.LocalFolder.CreateFileAsync(filename, CreationCollisionOption.ReplaceExisting);
        IRandomAccessStream sessionRandomAccess = await sessionFile.OpenAsync(FileAccessMode.ReadWrite);
        IOutputStream sessionOutputStream = sessionRandomAccess.GetOutputStreamAt(0);
        var serializer = new XmlSerializer(typeof(List<User>), new Type[] { typeof(T) });

        //Using XmlSerializer
        serializer.Serialize(sessionOutputStream.AsStreamForWrite(), _personen);
        sessionRandomAccess.Dispose();
        await sessionOutputStream.FlushAsync();
        sessionOutputStream.Dispose();
    }
}
公共类用户列表
{
私有静态列表_personen=新列表();
公开名单人员
{
获取{return\u personen;}
设置{u personen=value;}
}
公共静态存储文件{get;set;}
private const string filename=“Personen.xml”;
公共用户列表()
{
md.Title=“Fehler beim Speichen”;
Personen=新列表()
{
新用户(){ID=1,
Name=“TestUser1”},
新用户(){ID=2,
Name=“TestUser2”}
};
}
公共异步任务SpeicherUser()
{
等待保存();
}
静态异步公共任务保存()
{
如果(等待DoesFileExistAsync(文件名))
{
//AggregateException会在此处弹出:UserList.SaveAsync().Wait()
等待Windows.System.Threading.ThreadPool.RunAsync((发送方)=>UserList.SaveAsync().Wait(),Windows.System.Threading.WorkItemPriority.Normal);
}
其他的
{
file=wait ApplicationData.Current.LocalFolder.CreateFileAsync(文件名,CreationCollisionOption.ReplaceExisting);
}
}
静态异步任务DoesFileExistAsync(字符串文件名)
{
尝试
{
等待ApplicationData.Current.LocalFolder.GetFileAsync(文件名);
返回true;
}
抓住
{
返回false;
}
}
静态异步专用任务SaveAsync()
{
StorageFile sessionFile=await ApplicationData.Current.LocalFolder.CreateFileAsync(文件名,CreationCollisionOption.ReplaceExisting);
irandomaccesstream sessionRandomAccess=wait sessionFile.OpenAsync(FileAccessMode.ReadWrite);
IOOutputStream sessionOutputStream=sessionRandomAccess.GetOutputStreamAt(0);
var serializer=newxmlserializer(typeof(List),newtype[]{typeof(T)});
//使用XmlSerializer
serializer.Serialize(sessionOutputStream.AsStreamForWrite(),_personen);
sessionRandomAccess.Dispose();
等待sessionOutputStream.FlushAsync();
sessionOutputStream.Dispose();
}
}
用户列表显示在列表视图中。我现在有1个按钮,因此当用户单击按钮时,一个新的“用户”将添加到ListView中,并在它之后创建XML文件。为了解决我的问题,我可以使用两个按钮进行wordkaround: -一个用于将用户添加到ListView中 -另一个仅在用户创建新用户时启用。因此,XML文件将被保存,按钮将被禁用。 但这不是一个真正的解决方案。。。就像我说的,这只是一个解决办法,而不是真正解决问题


问题:如何处理
静态异步公共任务保存()
中的AggregateException,该异常表示“发生了一个或多个错误”。->拒绝访问(来自HRESULT的异常:0x80070005(EACCESSDENIED)

异步编程确实迫使您以稍微不同的方式设计UI。在这种情况下,您的UI有一个额外的状态,即创建用户

处理这些短期状态的一种常见方法是在操作过程中禁用按钮,例如:

async void AddButton_Click(..)
{
  addButton.IsEnabled = false;
  await Save();
  AddToListView();
  addButton.IsEnabled = true;
}

或者,您可以捕获异常并忽略它(因为这可能意味着已经有一个
添加
正在进行)。

我不确定忽略异常是一个好主意,因为它可能是一个真正的问题。这一点很好。“拒绝访问”太宽泛了,不能假设它是一个已经打开的句柄。是的,这实际上更简单。我不知道为什么我会想出两个按钮,当我可以打开/禁用一个按钮时…这不是关于如何处理异常的答案,但它是一个解决方案,所以我将它作为一个答案。