dpjo15650 2018-10-13 10:42
浏览 68
已采纳

如何以共享库的形式异步返回函数的进度

So I want to make a function for download a file in golang using this method below, I build this golang project into C .dll using

go build -buildmode=c-shared -o patcher.dll main.go

I managed to use this function on my C# application to get progress of file download, my current function (DownloadFfile) works if I just print it directly using DownloadFile() , however i want to get the progress asynchronously on my C# application , but i can't get the value directly, so I think I need to return integer of progress from my golang application but if I do that the function just go 1 times (the last result of progress)

The question is how to make my go func DownloadFile being called 1 times on my C# application but I can still keep track the progress ? Any help will be appreciated , thank you.

func DownloadFile(){
    // create client
    client := grab.NewClient()
    req, _ := grab.NewRequest(".", "http://www.golang-book.com/public/pdf/gobook.pdf")

    // start download
    fmt.Printf("Downloading %v...
", req.URL())
    resp := client.Do(req)
    fmt.Printf("  %v
", resp.HTTPResponse.Status)

    // start UI loop
    t := time.NewTicker(500 * time.Millisecond)
    defer t.Stop()

Loop:
    for {
        select {
        case <-t.C:
            fmt.Printf("%.2f%",
                //resp.BytesComplete(),
                //resp.Size,
                100*resp.Progress())

        case <-resp.Done:
            // download is complete
            break Loop
        }
    }

    // check for errors
    if err := resp.Err(); err != nil {
        fmt.Fprintf(os.Stderr, "Download failed: %v
", err)
        os.Exit(1)
    }

    // fmt.Printf("Download saved to ./%v 
", resp.Filename)

    // Output:
    // Downloading http://www.golang-book.com/public/pdf/gobook.pdf...
    //   200 OK
    //   transferred 42970 / 2893557 bytes (1.49%)
    //   transferred 1207474 / 2893557 bytes (41.73%)
    //   transferred 2758210 / 2893557 bytes (95.32%)
    // Download saved to ./gobook.pdf
}
  • 写回答

1条回答 默认 最新

  • dpauxqt1281 2018-10-13 18:58
    关注

    So, after digging out Google, I found the answer, I need to make setter and getter "a like" on Go like below.

    var Progress int
    var DownloadSpeed int
    
    //export DownloadFile
    func DownloadFile(){
        // create client
        client := grab.NewClient()
        req, _ := grab.NewRequest(".", "https://upload.wikimedia.org/wikipedia/commons/d/d6/Wp-w4-big.jpg")
    
        // start download
        fmt.Printf("Downloading %v...
    ", req.URL())
        resp := client.Do(req)
        fmt.Printf("  %v
    ", resp.HTTPResponse.Status)
    
        // start UI loop
        t := time.NewTicker(500 * time.Millisecond)
        defer t.Stop()
    
    Loop:
        for {
            select {
            case <-t.C:
    
                //progress = 100*(resp.Progress())
    
                SetProgressValue(int(resp.Progress() * 100))
                SetDownloadSpeedValue(int(resp.BytesPerSecond()))
                //fmt.Println(progress)
            case <-resp.Done:
                // download is complete
                SetProgressValue(100)
                //fmt.Println(Progress)
                break Loop
            }
        }
    
        // check for errors
        if err := resp.Err(); err != nil {
            fmt.Fprintf(os.Stderr, "Download failed: %v
    ", err)
            os.Exit(1)
        }
    
        fmt.Printf("Download saved to ./%v 
    ", resp.Filename)
        fmt.Println("Completed")
    }
    
    //export ProgressValue
    func ProgressValue() int {
        return Progress
    }
    
    //export SetProgressValue
    func SetProgressValue(val int) {
        Progress = val
    }
    

    Then usage in C# :

     void worker_DoWork(object sender, DoWorkEventArgs e) {
        [DllImport(@"M:\GolangProjects\PatcherDLL\patcher.dll", EntryPoint = "ProgressValue")]
         static extern int ProgressValue();
    
        public partial class MainWindow : Window {
        var task = Task.Factory.StartNew(() => {
                        DownloadFile();
                    });
    
                    while (!task.IsCompleted)
                    {
                        Thread.Sleep(100);
    
                        string downloadSpeedFormatted = "";
    
                        if (DownloadSpeedValue()/1000 > 999)
                        {
                            downloadSpeedFormatted = Math.Round((double) DownloadSpeedValue() / 1000000, 2) + " MB/s";
                        } else
                        {
                            downloadSpeedFormatted = DownloadSpeedValue() / 1000 + " kb/s";
                        }
    
                        Dispatcher.BeginInvoke(new Action(delegate {
                            progressbar1.Value = ProgressValue();
                            progressPercent1.Text = ProgressValue() + "%";
                            downloadSpeeds.Content = downloadSpeedFormatted;
                        }));
                    }
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 RPA正常跑,cmd输入cookies跑不出来
  • ¥15 求帮我调试一下freefem代码
  • ¥15 matlab代码解决,怎么运行
  • ¥15 R语言Rstudio突然无法启动
  • ¥15 关于#matlab#的问题:提取2个图像的变量作为另外一个图像像元的移动量,计算新的位置创建新的图像并提取第二个图像的变量到新的图像
  • ¥15 改算法,照着压缩包里边,参考其他代码封装的格式 写到main函数里
  • ¥15 用windows做服务的同志有吗
  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。