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 孟德尔随机化结果不一致
  • ¥15 深度学习残差模块模型
  • ¥50 怎么判断同步时序逻辑电路和异步时序逻辑电路
  • ¥15 差动电流二次谐波的含量Matlab计算
  • ¥15 Can/caned 总线错误问题,错误显示控制器要发1,结果总线检测到0
  • ¥15 C#如何调用串口数据
  • ¥15 MATLAB与单片机串口通信
  • ¥15 L76k模块的GPS的使用
  • ¥15 请帮我看一看数电项目如何设计
  • ¥23 (标签-bug|关键词-密码错误加密)