UWP FileIO используется другим процессом с текстовым файлом размером более 20 000 КБ - PullRequest
0 голосов
/ 27 августа 2018

У меня проблема с FileIO. Это продолжало с ошибкой "в использовании другим процессом". ниже изображение этого.

another process use it, so a process can't access

так, с большим количеством отладки .. Я обнаружил, что у меня есть проблема с частью "await FileIo.AppendTextAsync ()". ниже захват этого. если вы увеличите масштаб, вы увидите ошибку try-catch справа внизу. System.IO.FileLoadException

Чтобы решить эту проблему, я использовал семафор, чтобы убедиться, что один процесс может получить доступ к FileIO, даже к исходному источнику, а также обеспечить только один процесс FileIO. Но это не сработало. ошибка снова (используется другим процессом)

ниже мой исходный код.

    public async Task<List<string>> DoRandom(FileLists fl, StorageFolder folder, StorageFile another_file, int k)
   {
        FileLists retLists = new FileLists();
        List<string> encodingList = new List<string>();

        if (Option1)
        {
            foreach (UploadedFile i in fl)
            {
                await i.setOutFile(folder); // wait until setOutFile ends
                // read stream from storagefile
                using (Stream s = await i.originFile.OpenStreamForReadAsync())
                {
                    // streamreader from stream
                    using (StreamReader sr = new StreamReader(s))
                    {

                        string str = await sr.ReadToEndAsync();
                        StringBuilder stringBuilder = new StringBuilder(str);

                        string[] vs =
                            str.Split(new string[] { "\n", "\r\n", "\r" }, StringSplitOptions.None); 

                        foreach (var j in vs)
                        {
                           // try
                            {
                                await FileIO.AppendTextAsync(i.outputFile, j); // <--- real Problem Point
                            }
                            //catch { }
                        }
                    }
                }
            }
        }

и функция DoRandom вызывается функцией ниже.

  private async void StartButton_Click(object sender, RoutedEventArgs e)
    {

        /** non important source is omitted **/
        var picker = new Windows.Storage.Pickers.FolderPicker();

        picker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.Desktop;
        picker.FileTypeFilter.Add("*");

        StorageFolder folder = await picker.PickSingleFolderAsync();

        if (folder != null)
        {
            await myRandomizer.DoRandom(uploadedFileLists, folder, another_file, k);
            /*
            foreach (string str in fileEncoding)
            {
                var messageDialog = new MessageDialog(str);
                messageDialog.Title = str;
                await messageDialog.ShowAsync();
            }
            */
        }

    }
}

Я действительно расстроен, потому что не могу понять, что не так с моим источником. Я только что сделал источник для работы со строкой (split и foreach в этой строке). В выходном файле некоторые строки существуют (но не все строки).

и, как вы можете видеть, в моем источнике у меня есть "option1". это означает, что у меня есть несколько вариантов тоже. но другие работают хорошо. но option1 (с более чем 20 000 КБ текстовым файлом) всегда делает ошибку. что не так с моим источником?

Error Occured

ниже - мой класс и его источник setOutFile.

class UploadedFile
{
    public StorageFile originFile;
    public StorageFile outputFile { get; set; }
    // ....omitted
   public async Task setOutFile(StorageFolder folder)
    {
        var rand = new Random();
        string charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
        StringBuilder result = new StringBuilder(13);

        for (int i=0; i<13; i++)
        {
            result.Append(charset[rand.Next(charset.Length)]);
        }
        StringBuilder outputName = new StringBuilder();

        outputName.Append(inputName.Substring(0, inputName.Length - 4));
        outputName.Append("_");
        outputName.Append(result);
        outputName.Append(".txt");
        this.outputName = outputName.ToString();

        if (folder != null)
        {
            outputFile = await folder.CreateFileAsync(outputName.ToString(), CreationCollisionOption.ReplaceExisting);
        }
    }

1 Ответ

0 голосов
/ 28 августа 2018

Спасибо всем вашим комментариям. Я думаю, что проблема была, как вы сказали, и Visual Studio уведомили, что некоторый процесс "заблокирован" FileIO.

На самом деле, я не знал четко, в чем заключается моя проблема, пока не встретил совет @Johnny Westlake. Я просто обновил Visual Studio и перезагрузил Windows. Казалось, работа хорошая.

поэтому я подумал, что предыдущий исходный код (более старый, чем я опубликовал) сделал некоторую ошибку в Windows, и он закончился, пока остался какой-то процесс.

но это неправда, что проблема, похоже, решена. когда я помещаю много входного файла в мое приложение, мое приложение снова останавливается. Итак, я использовал синтаксис try-catch.

наконец, я изменил свой источник с "FILEIO.AppendTextAsync" на "FILEIO.WriteTextAsync" (как совет Джонни Уэстлейка). и с большим количеством отладки нет остановок, в конце концов мне не нужен синтаксис try-catch.

также его время работы (сложность по времени) снижается с 10 ~ 20 секунд до менее 1 секунды (при большом вводе файла)

ниже мой исходный код.

       public async Task<List<string>> DoRandom(FileLists fl, StorageFolder folder, StorageFile another_file, int k)
   {
        FileLists retLists = new FileLists();
        List<string> encodingList = new List<string>();

        if (Option1)
        {
            foreach (UploadedFile i in fl)
            {
                await i.setOutFile(folder); // wait until setOutFile ends
                // read stream from storagefile
                using (Stream s = await i.originFile.OpenStreamForReadAsync())
                {
                    // streamreader from stream
                    using (StreamReader sr = new StreamReader(s))
                    {

                        string str = await sr.ReadToEndAsync();
                        StringBuilder stringBuilder = new StringBuilder(str);
                        List<string> ans = doOption1(stringBuilder, k);
                        StringBuilder ret = new StringBuilder();
                        foreach (var j in ans)
                        {
                            ret.Append(j); //<--- append all string
                        }
                        await FileIO.WriteTextAsync(i.outputFile, ret.ToString()); // <-- write it at one time
                    }
                }
            }
...