C# 异步方法有时永远不会结束

C# 异步方法有时永远不会结束,c#,task,.net-4.5,async-await,C#,Task,.net 4.5,Async Await,我正在拍摄图像并进行处理。 然后我尝试将位图(这些图像)保存到一个文件中 比如说 我拍摄了“沙漠”和“花”的图像,并对它们进行了4次异步处理 然后我调用(等待)8次saveAsync()方法来保存它们 所发生的情况是保存沙漠和花的修改、花的修改(1)、花的修改(2)、花的修改(3) 没有修改过的图像(1)、修改过的图像(2)和修改过的图像(3) 将要保存它们的方法永远不会结束。有什么建议吗 async private Task saveAsync(Bitmap bitmap, Strin

我正在拍摄图像并进行处理。 然后我尝试将位图(这些图像)保存到一个文件中

比如说

  • 我拍摄了“沙漠”和“花”的图像,并对它们进行了4次异步处理
  • 然后我调用(等待)8次saveAsync()方法来保存它们

    • 所发生的情况是保存沙漠和花的修改、花的修改(1)、花的修改(2)、花的修改(3)
    • 没有修改过的图像(1)、修改过的图像(2)和修改过的图像(3)
将要保存它们的方法永远不会结束。有什么建议吗

async private Task saveAsync(Bitmap bitmap, String path, String fileName, int requestNo)
{
    int temp = 1;
    String pth = path;
    String fileName1 = fileName;
    try
    {
        await Task.Run(() =>
            {

                if (File.Exists(pth))
                {

                    String[] array = fileName1.Split('.');
                    String modifiedFileName = array[0] + "_modified" + "(" + temp + ")." + array[1];
                    pth = fullPath.Replace(fileName1, modifiedFileName);

                    while (File.Exists(pth))
                    {
                        temp++;
                        //array = fileName.Split('.');
                        modifiedFileName = array[0] + "_modified" + "(" + temp + ")." + array[1];
                        pth = fullPath.Replace(fileName1, modifiedFileName);

                    }

                    bitmap.Save(@pth);

                }
                else
                {
                    bitmap.Save(@pth);
                }
                bitmap.Dispose();
            });

    }
    catch (Exception ex)
    {
        outputTextBox2.Text += ex.InnerException.Message;
    }
}
你使用,这在这里是不合适的。 我认为代码中的主要错误是,您试图在while循环中替换
pth
中的
fileName1
,尽管fileName1没有出现在
pth
中,因为它是在while循环之前修改的因此,
pth
在while循环中永远不会更改,这就是while循环永不结束的原因

若要解决此问题,请使用
pth=fullPath.Replace(pth,modifiedFileName)
pth=modifiedFileName
,我的建议是:
pth=modifiedFileName

无论如何,使用
Replace
不会节省任何内存,因为C#中的字符串以及许多其他语言中的字符串都是不可变的!因此,即使通过
Replace
,也会生成一个新字符串

编辑:。。。隐马尔可夫模型。。也许这个答案并不完全正确,因为您正在处理
fullPath
,但另一方面,
fullPath
没有在这个函数中定义:)。。这是从哪里来的?

您使用的,实际上在这里并不合适。 我认为代码中的主要错误是,您试图在while循环中替换
pth
中的
fileName1
,尽管fileName1没有出现在
pth
中,因为它是在while循环之前修改的因此,
pth
在while循环中永远不会更改,这就是while循环永不结束的原因

若要解决此问题,请使用
pth=fullPath.Replace(pth,modifiedFileName)
pth=modifiedFileName
,我的建议是:
pth=modifiedFileName

无论如何,使用
Replace
不会节省任何内存,因为C#中的字符串以及许多其他语言中的字符串都是不可变的!因此,即使通过
Replace
,也会生成一个新字符串


编辑:。。。隐马尔可夫模型。。也许这个答案并不完全正确,因为您正在处理
fullPath
,但另一方面,
fullPath
没有在这个函数中定义:)。。这是从哪里来的?

如果您有兴趣改进代码,正如我在评论中所暗示的,那么以下是一个开始:

正如你所看到的,这个

  • 删除(名称混乱的)局部变量,如
    pth
    fileName1
    modifiedFileName
  • 不再滥用
    Split
    来(错误地)剖析路径(如果目录有扩展名怎么办?如果文件名包含
    本身怎么办?)
  • 使用
    PathCombine
    获取正确的路径分隔符
  • 使用固定格式字符串轻松生成候选文件名
  • 使用单个
    do while
    循环,而不是复制生成文件名的行
总的来说,我认为这要简单得多

我在本地PC上制作了一个简单的独立测试程序,以便实际测试:

using System.IO;
using System;

public class X
{
    public class Bitmap : IDisposable { 
        public void Dispose() { } 
        public void Save(string location)
        {
            Console.WriteLine("Saving: {0}", location);
            using (var s = new StreamWriter(location))
                s.WriteLine("hello world");
        }
    }

    private static void saveAsync(Bitmap bitmap, String path, String fileName, int requestNo)
    {
        Action a = () =>
          {
              var fmt = Path.Combine(path, Path.GetFileNameWithoutExtension(fileName)) + "_modified{0}" + Path.GetExtension(fileName);

              int counter = 1;
              string newName;
              do {
                  newName = string.Format(fmt, counter++);
              }
              while (File.Exists(newName));

              using (bitmap)
                  bitmap.Save(newName);
          };

        a();
        a();
        a();
        a();
    }

    public static void Main()
    {
        saveAsync(new Bitmap(), "/tmp", "foo.png", 3);
    }
}
这张照片

Saving: /tmp/foo_modified1.png
Saving: /tmp/foo_modified2.png
Saving: /tmp/foo_modified3.png
Saving: /tmp/foo_modified4.png

如果您对改进代码感兴趣,正如我在评论中所暗示的,那么以下是一个开始:

正如你所看到的,这个

  • 删除(名称混乱的)局部变量,如
    pth
    fileName1
    modifiedFileName
  • 不再滥用
    Split
    来(错误地)剖析路径(如果目录有扩展名怎么办?如果文件名包含
    本身怎么办?)
  • 使用
    PathCombine
    获取正确的路径分隔符
  • 使用固定格式字符串轻松生成候选文件名
  • 使用单个
    do while
    循环,而不是复制生成文件名的行
总的来说,我认为这要简单得多

我在本地PC上制作了一个简单的独立测试程序,以便实际测试:

using System.IO;
using System;

public class X
{
    public class Bitmap : IDisposable { 
        public void Dispose() { } 
        public void Save(string location)
        {
            Console.WriteLine("Saving: {0}", location);
            using (var s = new StreamWriter(location))
                s.WriteLine("hello world");
        }
    }

    private static void saveAsync(Bitmap bitmap, String path, String fileName, int requestNo)
    {
        Action a = () =>
          {
              var fmt = Path.Combine(path, Path.GetFileNameWithoutExtension(fileName)) + "_modified{0}" + Path.GetExtension(fileName);

              int counter = 1;
              string newName;
              do {
                  newName = string.Format(fmt, counter++);
              }
              while (File.Exists(newName));

              using (bitmap)
                  bitmap.Save(newName);
          };

        a();
        a();
        a();
        a();
    }

    public static void Main()
    {
        saveAsync(new Bitmap(), "/tmp", "foo.png", 3);
    }
}
这张照片

Saving: /tmp/foo_modified1.png
Saving: /tmp/foo_modified2.png
Saving: /tmp/foo_modified3.png
Saving: /tmp/foo_modified4.png

道歉。。我才意识到我错了。咖啡时间!顺便看一下System.IO.FileInfo。它将为您提供更好的修改文件名的方法。我添加了一个答案,说明了我的意思。我用IO.Path代替了道歉。。我才意识到我错了。咖啡时间!顺便看一下System.IO.FileInfo。它将为您提供更好的修改文件名的方法。我添加了一个答案,说明了我的意思。我使用了IO.Path INSTEAD,但
完整路径
也有同样的问题。我假设它是一个类成员,或者是一个复制/粘贴的人工制品,因为它需要对代码进行多次修改(试图让它工作)?无论如何,我有,假设完整路径应该从
路径
文件名
(现在仍然忽略
requestNo
)组合而成,我对
完整路径
也有同样的问题。我假设它是一个类成员,或者是一个复制/粘贴的人工制品,因为它需要对代码进行多次修改(试图让它工作)?无论如何,我已经,假设完整路径应该是从
路径
文件名
(现在仍然忽略
requestNo
)组合而成的,非常感谢。它起作用了。因为我是c#的新手,你的回答对我来说很有启发性。非常感谢。它起作用了。因为我是c#的新手,你的回答对我来说很有启发性。